1 /////////////////////////////////////////////////////////////////////////
2 // $Id: ne2k.cc 14284 2021-06-17 21:04:35Z vruppert $
3 /////////////////////////////////////////////////////////////////////////
4 //
5 //  Copyright (C) 2001-2021  The Bochs Project
6 //
7 //  This library is free software; you can redistribute it and/or
8 //  modify it under the terms of the GNU Lesser General Public
9 //  License as published by the Free Software Foundation; either
10 //  version 2 of the License, or (at your option) any later version.
11 //
12 //  This library is distributed in the hope that it will be useful,
13 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
14 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 //  Lesser General Public License for more details.
16 //
17 //  You should have received a copy of the GNU Lesser General Public
18 //  License along with this library; if not, write to the Free Software
19 //  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
20 /////////////////////////////////////////////////////////////////////////
21 
22 // Peter Grehan (grehan@iprg.nokia.com) coded the initial version of this
23 // NE2000/ether stuff.
24 
25 // Define BX_PLUGGABLE in files that can be compiled into plugins.  For
26 // platforms that require a special tag on exported symbols, BX_PLUGGABLE
27 // is used to know when we are exporting symbols and when we are importing.
28 #define BX_PLUGGABLE
29 
30 #include "iodev.h"
31 
32 #if BX_SUPPORT_NE2K
33 
34 #if BX_SUPPORT_PCI
35 #include "pci.h"
36 #endif
37 #include "ne2k.h"
38 #include "netmod.h"
39 
40 //Never completely fill the ne2k ring so that we never
41 // hit the unclear completely full buffer condition.
42 #define BX_NE2K_NEVER_FULL_RING (1)
43 
44 #define LOG_THIS NE2kDevMain->
45 
46 bx_ne2k_main_c *NE2kDevMain = NULL;
47 
48 #define BX_NE2K_TYPE_ISA  1
49 #define BX_NE2K_TYPE_PCI  2
50 
51 const char *ne2k_types_list[] = {"isa", "pci", NULL};
52 
53 const Bit8u ne2k_iomask[32] = {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
54                                7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
55 
56 // builtin configuration handling functions
57 
ne2k_init_options(void)58 void ne2k_init_options(void)
59 {
60   char name[12], label[16];
61   bx_list_c *deplist;
62 
63   bx_param_c *network = SIM->get_param("network");
64   for (Bit8u card = 0; card < BX_NE2K_MAX_DEVS; card++) {
65     sprintf(name, "ne2k%d", card);
66     sprintf(label, "NE2000 #%d", card);
67     bx_list_c *menu = new bx_list_c(network, name, label);
68     menu->set_options(menu->SHOW_PARENT | menu->SERIES_ASK);
69     bx_param_bool_c *enabled = new bx_param_bool_c(menu,
70       "enabled",
71       "Enable NE2K NIC emulation",
72       "Enables the NE2K NIC emulation",
73       (card==0));
74     bx_param_enum_c *type = new bx_param_enum_c(menu,
75       "type",
76       "Type of NE2K NIC emulation",
77       "Type of the NE2K NIC emulation",
78       ne2k_types_list,
79       BX_NE2K_TYPE_ISA,
80       BX_NE2K_TYPE_ISA);
81     bx_param_num_c *ioaddr = new bx_param_num_c(menu,
82       "ioaddr",
83       "NE2K I/O Address",
84       "I/O base address of the emulated NE2K device",
85       0, 0xffff,
86       0x300);
87     ioaddr->set_base(16);
88     bx_param_num_c *irq = new bx_param_num_c(menu,
89       "irq",
90       "NE2K Interrupt",
91       "IRQ used by the NE2K device",
92       0, 15,
93       9);
94     irq->set_options(irq->USE_SPIN_CONTROL);
95     SIM->init_std_nic_options(label, menu);
96     deplist = menu->clone();
97     deplist->remove("ioaddr");
98     deplist->remove("irq");
99     deplist->remove("bootrom");
100     enabled->set_dependent_list(deplist);
101     deplist = new bx_list_c(NULL);
102     deplist->add(ioaddr);
103     deplist->add(irq);
104     deplist->add(menu->get_by_name("bootrom"));
105     type->set_dependent_list(deplist, 0);
106     type->set_dependent_bitmap(BX_NE2K_TYPE_ISA, 0x3);
107     type->set_dependent_bitmap(BX_NE2K_TYPE_PCI, 0x4);
108   }
109 }
110 
ne2k_options_parser(const char * context,int num_params,char * params[])111 Bit32s ne2k_options_parser(const char *context, int num_params, char *params[])
112 {
113   int ret, card = 0, first = 1, valid = 0;
114   char pname[16];
115 
116   if (!strcmp(params[0], "ne2k")) {
117     if (!strncmp(params[1], "card=", 5)) {
118       card = atol(&params[1][5]);
119       if ((card < 0) || (card >= BX_NE2K_MAX_DEVS)) {
120         BX_ERROR(("%s: 'ne2k' directive: illegal card number", context));
121       }
122       first = 2;
123     }
124     sprintf(pname, "%s%d", BXPN_NE2K, card);
125     bx_list_c *base = (bx_list_c*) SIM->get_param(pname);
126     if (!SIM->get_param_bool("enabled", base)->get()) {
127       SIM->get_param_enum("ethmod", base)->set_by_name("null");
128     }
129     if (!SIM->get_param_string("mac", base)->isempty()) {
130       // MAC address is already initialized
131       valid |= 0x04;
132     }
133     if (card == 0) {
134       if (SIM->is_pci_device("ne2k")) {
135         SIM->get_param_enum("type", base)->set(BX_NE2K_TYPE_PCI);
136       } else {
137         SIM->get_param_enum("type", base)->set(BX_NE2K_TYPE_ISA);
138       }
139     }
140     for (int i = first; i < num_params; i++) {
141       if (!strncmp(params[i], "type=", 5)) {
142         SIM->get_param_enum("type", base)->set_by_name(&params[i][5]);
143         valid |= 0x08;
144       } else if (!strncmp(params[i], "ioaddr=", 7)) {
145         SIM->get_param_num("ioaddr", base)->set(strtoul(&params[i][7], NULL, 16));
146         valid |= 0x01;
147       } else if (!strncmp(params[i], "irq=", 4)) {
148         SIM->get_param_num("irq", base)->set(atol(&params[i][4]));
149         valid |= 0x02;
150       } else {
151         ret = SIM->parse_nic_params(context, params[i], base);
152         if (ret > 0) {
153           valid |= ret;
154         }
155       }
156     }
157     if (SIM->get_param_enum("type", base)->get() == BX_NE2K_TYPE_PCI) {
158       valid |= 0x10;
159     }
160     if ((valid & 0xc0) == 0) {
161       SIM->get_param_bool("enabled", base)->set(1);
162     }
163     if (valid < 0x80) {
164       if (((valid & 0x10) == 0) && ((valid & 0x03) != 0x03)) {
165         BX_ERROR(("%s: 'ne2k' directive incomplete (ioaddr and irq are required)", context));
166         valid |= 0x80;
167       }
168       if ((valid & 0x04) == 0) {
169         BX_ERROR(("%s: 'ne2k' directive incomplete (mac address is required)", context));
170         valid |= 0x80;
171       }
172       if ((valid & 0x80) != 0) {
173         SIM->get_param_bool("enabled", base)->set(0);
174       }
175     }
176   } else {
177     BX_PANIC(("%s: unknown directive '%s'", context, params[0]));
178   }
179   return 0;
180 }
181 
ne2k_options_save(FILE * fp)182 Bit32s ne2k_options_save(FILE *fp)
183 {
184   char pname[16], ne2kstr[20];
185 
186   for (Bit8u card = 0; card < BX_NE2K_MAX_DEVS; card++) {
187     sprintf(pname, "%s%d", BXPN_NE2K, card);
188     sprintf(ne2kstr, "ne2k: card=%d, ", card);
189     SIM->write_param_list(fp, (bx_list_c*) SIM->get_param(pname), ne2kstr, 0);
190   }
191   return 0;
192 }
193 
194 // device plugin entry point
195 
PLUGIN_ENTRY_FOR_MODULE(ne2k)196 PLUGIN_ENTRY_FOR_MODULE(ne2k)
197 {
198   if (mode == PLUGIN_INIT) {
199     NE2kDevMain = new bx_ne2k_main_c();
200     BX_REGISTER_DEVICE_DEVMODEL(plugin, type, NE2kDevMain, BX_PLUGIN_NE2K);
201     // add new configuration parameter for the config interface
202     ne2k_init_options();
203     // register add-on option for bochsrc and command line
204     SIM->register_addon_option("ne2k", ne2k_options_parser, ne2k_options_save);
205   } else if (mode == PLUGIN_FINI) {
206     char name[12];
207 
208     SIM->unregister_addon_option("ne2k");
209     bx_list_c *network = (bx_list_c*)SIM->get_param("network");
210     for (Bit8u card = 0; card < BX_NE2K_MAX_DEVS; card++) {
211       sprintf(name, "ne2k%d", card);
212       network->remove(name);
213     }
214     delete NE2kDevMain;
215   } else if (mode == PLUGIN_PROBE) {
216     return (int)PLUGTYPE_OPTIONAL;
217   } else if (mode == PLUGIN_FLAGS) {
218     return PLUGFLAG_PCI;
219   }
220   return(0); // Success
221 }
222 
223 // the main object creates up to 4 device objects
224 
bx_ne2k_main_c()225 bx_ne2k_main_c::bx_ne2k_main_c()
226 {
227   for (Bit8u card = 0; card < BX_NE2K_MAX_DEVS; card++) {
228     theNE2kDev[card] = NULL;
229   }
230 }
231 
~bx_ne2k_main_c()232 bx_ne2k_main_c::~bx_ne2k_main_c()
233 {
234   for (Bit8u card = 0; card < BX_NE2K_MAX_DEVS; card++) {
235     if (theNE2kDev[card] != NULL) {
236       delete theNE2kDev[card];
237     }
238   }
239 }
240 
init(void)241 void bx_ne2k_main_c::init(void)
242 {
243   Bit8u count = 0;
244   char pname[16];
245 
246   for (Bit8u card = 0; card < BX_NE2K_MAX_DEVS; card++) {
247     // Read in values from config interface
248     sprintf(pname, "%s%d", BXPN_NE2K, card);
249     bx_list_c *base = (bx_list_c*) SIM->get_param(pname);
250     if (SIM->get_param_bool("enabled", base)->get()) {
251       theNE2kDev[card] = new bx_ne2k_c();
252       theNE2kDev[card]->init(card);
253       count++;
254     }
255   }
256   // Check if the device plugin in use
257   if (count == 0) {
258     BX_INFO(("NE2000 disabled"));
259     // mark unused plugin for removal
260     ((bx_param_bool_c*)((bx_list_c*)SIM->get_param(BXPN_PLUGIN_CTRL))->get_by_name("ne2k"))->set(0);
261     return;
262   }
263 }
264 
reset(unsigned type)265 void bx_ne2k_main_c::reset(unsigned type)
266 {
267   for (Bit8u card = 0; card < BX_NE2K_MAX_DEVS; card++) {
268     if (theNE2kDev[card] != NULL) {
269       theNE2kDev[card]->reset(type);
270     }
271   }
272 }
273 
register_state()274 void bx_ne2k_main_c::register_state()
275 {
276   bx_list_c *list = new bx_list_c(SIM->get_bochs_root(), "ne2k", "NE2000 State");
277   for (Bit8u card = 0; card < BX_NE2K_MAX_DEVS; card++) {
278     if (theNE2kDev[card] != NULL) {
279       theNE2kDev[card]->ne2k_register_state(list, card);
280     }
281   }
282 }
283 
284 #if BX_SUPPORT_PCI
after_restore_state()285 void bx_ne2k_main_c::after_restore_state()
286 {
287   for (Bit8u card = 0; card < BX_NE2K_MAX_DEVS; card++) {
288     if (theNE2kDev[card] != NULL) {
289       theNE2kDev[card]->after_restore_state();
290     }
291   }
292 }
293 #endif
294 
295 // the device object
296 
297 #undef LOG_THIS
298 #define LOG_THIS
299 
bx_ne2k_c()300 bx_ne2k_c::bx_ne2k_c()
301 {
302   memset(&s, 0, sizeof(bx_ne2k_t));
303   s.tx_timer_index = BX_NULL_TIMER_HANDLE;
304   ethdev = NULL;
305 }
306 
307 
~bx_ne2k_c()308 bx_ne2k_c::~bx_ne2k_c()
309 {
310   if (ethdev != NULL) {
311     delete ethdev;
312   }
313   SIM->get_bochs_root()->remove("ne2k");
314   BX_DEBUG(("Exit"));
315 }
316 
init(Bit8u card)317 void bx_ne2k_c::init(Bit8u card)
318 {
319   char pname[20];
320   Bit8u macaddr[6];
321   bx_param_string_c *bootrom;
322 
323   BX_DEBUG(("Init $Id: ne2k.cc 14284 2021-06-17 21:04:35Z vruppert $"));
324 
325   // Read in values from config interface
326   sprintf(pname, "%s%d", BXPN_NE2K, card);
327   bx_list_c *base = (bx_list_c*) SIM->get_param(pname);
328   memcpy(macaddr, SIM->get_param_string("mac", base)->getptr(), 6);
329   sprintf(s.devname, "ne2k%d", card);
330   put(s.devname);
331   sprintf(s.ldevname, "NE2000 NIC #%d", card);
332   BX_NE2K_THIS s.pci_enabled = (SIM->get_param_enum("type", base)->get() == BX_NE2K_TYPE_PCI);
333 
334 #if BX_SUPPORT_PCI
335   if (BX_NE2K_THIS s.pci_enabled) {
336     sprintf(s.ldevname, "NE2000 PCI NIC #%d", card);
337     BX_NE2K_THIS s.devfunc = 0x00;
338     DEV_register_pci_handlers(this, &s.devfunc, BX_PLUGIN_NE2K, s.ldevname);
339 
340     // initialize readonly registers
341     init_pci_conf(0x10ec, 0x8029, 0x00, 0x020000, 0x00, BX_PCI_INTA);
342     BX_NE2K_THIS pci_conf[0x04] = 0x01;
343     BX_NE2K_THIS pci_conf[0x07] = 0x02;
344     init_bar_io(0, 32, read_handler, write_handler, &ne2k_iomask[0]);
345     BX_NE2K_THIS s.base_address = 0x0;
346     BX_NE2K_THIS pci_rom_address = 0;
347     BX_NE2K_THIS pci_rom_read_handler = mem_read_handler;
348     bootrom = SIM->get_param_string("bootrom", base);
349     if (!bootrom->isempty()) {
350       BX_NE2K_THIS load_pci_rom(bootrom->getptr());
351     }
352   }
353 #endif
354 
355   if (BX_NE2K_THIS s.tx_timer_index == BX_NULL_TIMER_HANDLE) {
356     BX_NE2K_THIS s.tx_timer_index =
357       DEV_register_timer(this, tx_timer_handler, 0, 0, 0,
358                          "ne2k"); // one-shot, inactive
359   }
360   // Register the IRQ and i/o port addresses
361   if (!BX_NE2K_THIS s.pci_enabled) {
362     BX_NE2K_THIS s.base_address = SIM->get_param_num("ioaddr", base)->get();
363     BX_NE2K_THIS s.base_irq     = SIM->get_param_num("irq", base)->get();
364 
365     DEV_register_irq(BX_NE2K_THIS s.base_irq, "NE2000 ethernet NIC");
366 
367     DEV_register_ioread_handler_range(BX_NE2K_THIS_PTR, read_handler,
368                                       BX_NE2K_THIS s.base_address,
369                                       BX_NE2K_THIS s.base_address + 0x0F,
370                                       s.ldevname, 3);
371     DEV_register_iowrite_handler_range(BX_NE2K_THIS_PTR, write_handler,
372                                        BX_NE2K_THIS s.base_address,
373                                        BX_NE2K_THIS s.base_address + 0x0F,
374                                        s.ldevname, 3);
375     DEV_register_ioread_handler(BX_NE2K_THIS_PTR, read_handler,
376                                 BX_NE2K_THIS s.base_address + 0x10,
377                                 s.ldevname, 3);
378     DEV_register_iowrite_handler(BX_NE2K_THIS_PTR, write_handler,
379                                  BX_NE2K_THIS s.base_address + 0x10,
380                                  s.ldevname, 3);
381     DEV_register_ioread_handler(BX_NE2K_THIS_PTR, read_handler,
382                                 BX_NE2K_THIS s.base_address + 0x1F,
383                                 s.ldevname, 1);
384     DEV_register_iowrite_handler(BX_NE2K_THIS_PTR, write_handler,
385                                  BX_NE2K_THIS s.base_address + 0x1F,
386                                  s.ldevname, 1);
387 
388     bootrom = SIM->get_param_string("bootrom", base);
389     if (!bootrom->isempty()) {
390       BX_PANIC(("%s: boot ROM support not present yet", s.ldevname));
391     }
392 
393     BX_INFO(("%s initialized port 0x%x/32 irq %d mac %02x:%02x:%02x:%02x:%02x:%02x",
394              s.ldevname,
395              BX_NE2K_THIS s.base_address,
396              BX_NE2K_THIS s.base_irq,
397              macaddr[0], macaddr[1],
398              macaddr[2], macaddr[3],
399              macaddr[4], macaddr[5]));
400   } else {
401     BX_INFO(("%s initialized mac %02x:%02x:%02x:%02x:%02x:%02x",
402              s.ldevname,
403              macaddr[0], macaddr[1],
404              macaddr[2], macaddr[3],
405              macaddr[4], macaddr[5]));
406   }
407 
408   // Initialise the mac address area by doubling the physical address
409   BX_NE2K_THIS s.macaddr[0]  = macaddr[0];
410   BX_NE2K_THIS s.macaddr[1]  = macaddr[0];
411   BX_NE2K_THIS s.macaddr[2]  = macaddr[1];
412   BX_NE2K_THIS s.macaddr[3]  = macaddr[1];
413   BX_NE2K_THIS s.macaddr[4]  = macaddr[2];
414   BX_NE2K_THIS s.macaddr[5]  = macaddr[2];
415   BX_NE2K_THIS s.macaddr[6]  = macaddr[3];
416   BX_NE2K_THIS s.macaddr[7]  = macaddr[3];
417   BX_NE2K_THIS s.macaddr[8]  = macaddr[4];
418   BX_NE2K_THIS s.macaddr[9]  = macaddr[4];
419   BX_NE2K_THIS s.macaddr[10] = macaddr[5];
420   BX_NE2K_THIS s.macaddr[11] = macaddr[5];
421 
422   // ne2k signature
423   for (int i = 12; i < 32; i++)
424     BX_NE2K_THIS s.macaddr[i] = 0x57;
425 
426   BX_NE2K_THIS s.statusbar_id = bx_gui->register_statusitem("NE2K", 1);
427 
428   // Attach to the selected ethernet module
429   BX_NE2K_THIS ethdev = DEV_net_init_module(base, rx_handler, rx_status_handler, this);
430 
431 #if BX_DEBUGGER
432   // register device for the 'info device' command (calls debug_dump())
433   bx_dbg_register_debug_info(s.devname, this);
434 #endif
435 }
436 
437 //
438 // reset - restore state to power-up, cancelling all i/o
439 //
reset(unsigned type)440 void bx_ne2k_c::reset(unsigned type)
441 {
442   if (type == BX_RESET_HARDWARE) {
443     // Zero out registers and memory
444     memset(&BX_NE2K_THIS s.CR,  0, sizeof(BX_NE2K_THIS s.CR));
445     memset(&BX_NE2K_THIS s.IMR, 0, sizeof(BX_NE2K_THIS s.IMR));
446     memset(&BX_NE2K_THIS s.DCR, 0, sizeof(BX_NE2K_THIS s.DCR));
447     memset(&BX_NE2K_THIS s.TCR, 0, sizeof(BX_NE2K_THIS s.TCR));
448     memset(&BX_NE2K_THIS s.TSR, 0, sizeof(BX_NE2K_THIS s.TSR));
449     memset(&BX_NE2K_THIS s.RCR, 0, sizeof(BX_NE2K_THIS s.RCR));
450     memset(&BX_NE2K_THIS s.RSR, 0, sizeof(BX_NE2K_THIS s.RSR));
451     BX_NE2K_THIS s.local_dma  = 0;
452     BX_NE2K_THIS s.page_start = 0;
453     BX_NE2K_THIS s.page_stop  = 0;
454     BX_NE2K_THIS s.bound_ptr  = 0;
455     BX_NE2K_THIS s.tx_page_start = 0;
456     BX_NE2K_THIS s.num_coll   = 0;
457     BX_NE2K_THIS s.tx_bytes   = 0;
458     BX_NE2K_THIS s.fifo       = 0;
459     BX_NE2K_THIS s.remote_dma = 0;
460     BX_NE2K_THIS s.remote_start = 0;
461     BX_NE2K_THIS s.remote_bytes = 0;
462     BX_NE2K_THIS s.tallycnt_0 = 0;
463     BX_NE2K_THIS s.tallycnt_1 = 0;
464     BX_NE2K_THIS s.tallycnt_2 = 0;
465 
466     memset(&BX_NE2K_THIS s.physaddr, 0, sizeof(BX_NE2K_THIS s.physaddr));
467     memset(&BX_NE2K_THIS s.mchash, 0, sizeof(BX_NE2K_THIS s.mchash));
468     BX_NE2K_THIS s.curr_page = 0;
469 
470     BX_NE2K_THIS s.rempkt_ptr   = 0;
471     BX_NE2K_THIS s.localpkt_ptr = 0;
472     BX_NE2K_THIS s.address_cnt  = 0;
473 
474     memset(&BX_NE2K_THIS s.mem, 0, sizeof(BX_NE2K_THIS s.mem));
475 
476     // Set power-up conditions
477     BX_NE2K_THIS s.CR.stop      = 1;
478     BX_NE2K_THIS s.CR.rdma_cmd  = 4;
479     BX_NE2K_THIS s.DCR.longaddr = 1;
480 
481     set_irq_level(0);
482   }
483   memset(&BX_NE2K_THIS s.ISR, 0, sizeof(BX_NE2K_THIS s.ISR));
484   BX_NE2K_THIS s.ISR.reset = 1;
485 }
486 
ne2k_register_state(bx_list_c * parent,Bit8u card)487 void bx_ne2k_c::ne2k_register_state(bx_list_c *parent, Bit8u card)
488 {
489   char pname[8];
490 
491   sprintf(pname, "%d", card);
492   bx_list_c *list = new bx_list_c(parent, pname, "NE2000 State");
493   bx_list_c *CR = new bx_list_c(list, "CR");
494   BXRS_PARAM_BOOL(CR, stop, BX_NE2K_THIS s.CR.stop);
495   BXRS_PARAM_BOOL(CR, start, BX_NE2K_THIS s.CR.start);
496   BXRS_PARAM_BOOL(CR, tx_packet, BX_NE2K_THIS s.CR.tx_packet);
497   new bx_shadow_num_c(CR, "rdma_cmd", &BX_NE2K_THIS s.CR.rdma_cmd);
498   new bx_shadow_num_c(CR, "pgsel", &BX_NE2K_THIS s.CR.pgsel);
499   bx_list_c *ISR = new bx_list_c(list, "ISR");
500   BXRS_PARAM_BOOL(ISR, pkt_rx, BX_NE2K_THIS s.ISR.pkt_rx);
501   BXRS_PARAM_BOOL(ISR, pkt_tx, BX_NE2K_THIS s.ISR.pkt_tx);
502   BXRS_PARAM_BOOL(ISR, rx_err, BX_NE2K_THIS s.ISR.rx_err);
503   BXRS_PARAM_BOOL(ISR, tx_err, BX_NE2K_THIS s.ISR.tx_err);
504   BXRS_PARAM_BOOL(ISR, overwrite, BX_NE2K_THIS s.ISR.overwrite);
505   BXRS_PARAM_BOOL(ISR, cnt_oflow, BX_NE2K_THIS s.ISR.cnt_oflow);
506   BXRS_PARAM_BOOL(ISR, rdma_done, BX_NE2K_THIS s.ISR.rdma_done);
507   BXRS_PARAM_BOOL(ISR, reset, BX_NE2K_THIS s.ISR.reset);
508   bx_list_c *IMR = new bx_list_c(list, "IMR");
509   BXRS_PARAM_BOOL(IMR, rx_inte, BX_NE2K_THIS s.IMR.rx_inte);
510   BXRS_PARAM_BOOL(IMR, tx_inte, BX_NE2K_THIS s.IMR.tx_inte);
511   BXRS_PARAM_BOOL(IMR, rxerr_inte, BX_NE2K_THIS s.IMR.rxerr_inte);
512   BXRS_PARAM_BOOL(IMR, txerr_inte, BX_NE2K_THIS s.IMR.txerr_inte);
513   BXRS_PARAM_BOOL(IMR, overw_inte, BX_NE2K_THIS s.IMR.overw_inte);
514   BXRS_PARAM_BOOL(IMR, cofl_inte, BX_NE2K_THIS s.IMR.cofl_inte);
515   BXRS_PARAM_BOOL(IMR, rdma_inte, BX_NE2K_THIS s.IMR.rdma_inte);
516   bx_list_c *DCR = new bx_list_c(list, "DCR");
517   BXRS_PARAM_BOOL(DCR, wdsize, BX_NE2K_THIS s.DCR.wdsize);
518   BXRS_PARAM_BOOL(DCR, endian, BX_NE2K_THIS s.DCR.endian);
519   BXRS_PARAM_BOOL(DCR, longaddr, BX_NE2K_THIS s.DCR.longaddr);
520   BXRS_PARAM_BOOL(DCR, loop, BX_NE2K_THIS s.DCR.loop);
521   BXRS_PARAM_BOOL(DCR, auto_rx, BX_NE2K_THIS s.DCR.auto_rx);
522   new bx_shadow_num_c(DCR, "fifo_size", &BX_NE2K_THIS s.DCR.fifo_size);
523   bx_list_c *TCR = new bx_list_c(list, "TCR");
524   BXRS_PARAM_BOOL(TCR, crc_disable, BX_NE2K_THIS s.TCR.crc_disable);
525   new bx_shadow_num_c(TCR, "loop_cntl", &BX_NE2K_THIS s.TCR.loop_cntl);
526   BXRS_PARAM_BOOL(TCR, ext_stoptx, BX_NE2K_THIS s.TCR.ext_stoptx);
527   BXRS_PARAM_BOOL(TCR, coll_prio, BX_NE2K_THIS s.TCR.coll_prio);
528   bx_list_c *TSR = new bx_list_c(list, "TSR");
529   BXRS_PARAM_BOOL(TSR, tx_ok, BX_NE2K_THIS s.TSR.tx_ok);
530   BXRS_PARAM_BOOL(TSR, collided, BX_NE2K_THIS s.TSR.collided);
531   BXRS_PARAM_BOOL(TSR, aborted, BX_NE2K_THIS s.TSR.aborted);
532   BXRS_PARAM_BOOL(TSR, no_carrier, BX_NE2K_THIS s.TSR.no_carrier);
533   BXRS_PARAM_BOOL(TSR, fifo_ur, BX_NE2K_THIS s.TSR.fifo_ur);
534   BXRS_PARAM_BOOL(TSR, cd_hbeat, BX_NE2K_THIS s.TSR.cd_hbeat);
535   BXRS_PARAM_BOOL(TSR, ow_coll, BX_NE2K_THIS s.TSR.ow_coll);
536   bx_list_c *RCR = new bx_list_c(list, "RCR");
537   BXRS_PARAM_BOOL(RCR, errors_ok, BX_NE2K_THIS s.RCR.errors_ok);
538   BXRS_PARAM_BOOL(RCR, runts_ok, BX_NE2K_THIS s.RCR.runts_ok);
539   BXRS_PARAM_BOOL(RCR, broadcast, BX_NE2K_THIS s.RCR.broadcast);
540   BXRS_PARAM_BOOL(RCR, multicast, BX_NE2K_THIS s.RCR.multicast);
541   BXRS_PARAM_BOOL(RCR, promisc, BX_NE2K_THIS s.RCR.promisc);
542   BXRS_PARAM_BOOL(RCR, monitor, BX_NE2K_THIS s.RCR.monitor);
543   bx_list_c *RSR = new bx_list_c(list, "RSR");
544   BXRS_PARAM_BOOL(RSR, rx_ok, BX_NE2K_THIS s.RSR.rx_ok);
545   BXRS_PARAM_BOOL(RSR, bad_crc, BX_NE2K_THIS s.RSR.bad_crc);
546   BXRS_PARAM_BOOL(RSR, bad_falign, BX_NE2K_THIS s.RSR.bad_falign);
547   BXRS_PARAM_BOOL(RSR, fifo_or, BX_NE2K_THIS s.RSR.fifo_or);
548   BXRS_PARAM_BOOL(RSR, rx_missed, BX_NE2K_THIS s.RSR.rx_missed);
549   BXRS_PARAM_BOOL(RSR, rx_mbit, BX_NE2K_THIS s.RSR.rx_mbit);
550   BXRS_PARAM_BOOL(RSR, rx_disabled, BX_NE2K_THIS s.RSR.rx_disabled);
551   BXRS_PARAM_BOOL(RSR, deferred, BX_NE2K_THIS s.RSR.deferred);
552   new bx_shadow_num_c(list, "local_dma", &BX_NE2K_THIS s.local_dma, BASE_HEX);
553   new bx_shadow_num_c(list, "page_start", &BX_NE2K_THIS s.page_start, BASE_HEX);
554   new bx_shadow_num_c(list, "page_stop", &BX_NE2K_THIS s.page_stop, BASE_HEX);
555   new bx_shadow_num_c(list, "bound_ptr", &BX_NE2K_THIS s.bound_ptr, BASE_HEX);
556   new bx_shadow_num_c(list, "tx_page_start", &BX_NE2K_THIS s.tx_page_start, BASE_HEX);
557   new bx_shadow_num_c(list, "num_coll", &BX_NE2K_THIS s.num_coll, BASE_HEX);
558   new bx_shadow_num_c(list, "tx_bytes", &BX_NE2K_THIS s.tx_bytes, BASE_HEX);
559   new bx_shadow_num_c(list, "fifo", &BX_NE2K_THIS s.fifo, BASE_HEX);
560   new bx_shadow_num_c(list, "remote_dma", &BX_NE2K_THIS s.remote_dma, BASE_HEX);
561   new bx_shadow_num_c(list, "remote_start", &BX_NE2K_THIS s.remote_start, BASE_HEX);
562   new bx_shadow_num_c(list, "remote_bytes", &BX_NE2K_THIS s.remote_bytes, BASE_HEX);
563   new bx_shadow_num_c(list, "tallycnt_0", &BX_NE2K_THIS s.tallycnt_0, BASE_HEX);
564   new bx_shadow_num_c(list, "tallycnt_1", &BX_NE2K_THIS s.tallycnt_1, BASE_HEX);
565   new bx_shadow_num_c(list, "tallycnt_2", &BX_NE2K_THIS s.tallycnt_2, BASE_HEX);
566   new bx_shadow_data_c(list, "physaddr", BX_NE2K_THIS s.physaddr, 6, 1);
567   new bx_shadow_num_c(list, "curr_page", &BX_NE2K_THIS s.curr_page, BASE_HEX);
568   new bx_shadow_data_c(list, "mchash", BX_NE2K_THIS s.mchash, 8, 1);
569   new bx_shadow_num_c(list, "rempkt_ptr", &BX_NE2K_THIS s.rempkt_ptr, BASE_HEX);
570   new bx_shadow_num_c(list, "localpkt_ptr", &BX_NE2K_THIS s.localpkt_ptr, BASE_HEX);
571   new bx_shadow_num_c(list, "address_cnt", &BX_NE2K_THIS s.address_cnt, BASE_HEX);
572   new bx_shadow_data_c(list, "mem", BX_NE2K_THIS s.mem, BX_NE2K_MEMSIZ);
573   BXRS_PARAM_BOOL(list, tx_timer_active, BX_NE2K_THIS s.tx_timer_active);
574 #if BX_SUPPORT_PCI
575   if (BX_NE2K_THIS s.pci_enabled) {
576     register_pci_state(list);
577   }
578 #endif
579 }
580 
581 #if BX_SUPPORT_PCI
after_restore_state(void)582 void bx_ne2k_c::after_restore_state(void)
583 {
584   if (BX_NE2K_THIS s.pci_enabled) {
585     bx_pci_device_c::after_restore_pci_state(mem_read_handler);
586   }
587 }
588 #endif
589 
590 //
591 // read_cr/write_cr - utility routines for handling reads/writes to
592 // the Command Register
593 //
read_cr(void)594 Bit32u bx_ne2k_c::read_cr(void)
595 {
596   Bit32u val =
597          (((BX_NE2K_THIS s.CR.pgsel    & 0x03) << 6) |
598           ((BX_NE2K_THIS s.CR.rdma_cmd & 0x07) << 3) |
599           (BX_NE2K_THIS s.CR.tx_packet         << 2) |
600           (BX_NE2K_THIS s.CR.start             << 1) |
601           (Bit8u)BX_NE2K_THIS s.CR.stop);
602   BX_DEBUG(("read CR returns 0x%02x", val));
603   return val;
604 }
605 
write_cr(Bit32u value)606 void bx_ne2k_c::write_cr(Bit32u value)
607 {
608   BX_DEBUG(("wrote 0x%02x to CR", value));
609 
610   // Validate remote-DMA
611   if ((value & 0x38) == 0x00) {
612     BX_DEBUG(("CR write - invalid rDMA value 0"));
613     value |= 0x20; /* dma_cmd == 4 is a safe default */
614   }
615 
616   // Check for s/w reset
617   if (value & 0x01) {
618     BX_NE2K_THIS s.ISR.reset = 1;
619     BX_NE2K_THIS s.CR.stop   = 1;
620   } else {
621     BX_NE2K_THIS s.CR.stop = 0;
622   }
623 
624   BX_NE2K_THIS s.CR.rdma_cmd = (value & 0x38) >> 3;
625 
626   // If start command issued, the RST bit in the ISR
627   // must be cleared
628   if ((value & 0x02) && !BX_NE2K_THIS s.CR.start) {
629     BX_NE2K_THIS s.ISR.reset = 0;
630   }
631 
632   BX_NE2K_THIS s.CR.start = ((value & 0x02) == 0x02);
633   BX_NE2K_THIS s.CR.pgsel = (value & 0xc0) >> 6;
634 
635   // Check for send-packet command
636   if (BX_NE2K_THIS s.CR.rdma_cmd == 3) {
637     // Set up DMA read from receive ring
638     BX_NE2K_THIS s.remote_start = BX_NE2K_THIS s.remote_dma = BX_NE2K_THIS s.bound_ptr * 256;
639     BX_NE2K_THIS s.remote_bytes = (Bit16u) chipmem_read(BX_NE2K_THIS s.bound_ptr * 256 + 2, 2);
640     BX_INFO(("Sending buffer #x%x length %d",
641       BX_NE2K_THIS s.remote_start,
642       BX_NE2K_THIS s.remote_bytes));
643   }
644 
645   // Check for start-tx
646   if ((value & 0x04) && BX_NE2K_THIS s.TCR.loop_cntl) {
647     if (BX_NE2K_THIS s.TCR.loop_cntl != 1) {
648       BX_INFO(("Loop mode %d not supported.", BX_NE2K_THIS s.TCR.loop_cntl));
649     } else {
650       rx_frame (& BX_NE2K_THIS s.mem[BX_NE2K_THIS s.tx_page_start*256 - BX_NE2K_MEMSTART],
651                 BX_NE2K_THIS s.tx_bytes);
652     }
653   } else if (value & 0x04) {
654     if (BX_NE2K_THIS s.CR.stop || (!BX_NE2K_THIS s.CR.start && !BX_NE2K_THIS s.pci_enabled)) {
655       if (BX_NE2K_THIS s.tx_bytes == 0) /* njh@bandsman.co.uk */
656         return; /* Solaris9 probe */
657       BX_PANIC(("CR write - tx start, dev in reset"));
658     }
659 
660     if (BX_NE2K_THIS s.tx_bytes == 0)
661       BX_PANIC(("CR write - tx start, tx bytes == 0"));
662 
663     // Send the packet to the system driver
664     BX_NE2K_THIS s.CR.tx_packet = 1;
665     Bit16u tx_start_ofs = BX_NE2K_THIS s.tx_page_start*256;
666     // The following test and decrement is required for Novell Netware
667     // 3.11-3.12, see
668     // https://lists.gnu.org/archive/html/qemu-devel/2005-03/msg00313.html
669     // for the corresponding change in QEMU.
670     if (tx_start_ofs >= BX_NE2K_MEMEND)
671       tx_start_ofs -= BX_NE2K_MEMSIZ;
672     if (tx_start_ofs + BX_NE2K_THIS s.tx_bytes > BX_NE2K_MEMEND)
673       BX_PANIC(("tx start with start offset %d and byte count %d would overrun memory",
674                 tx_start_ofs, BX_NE2K_THIS s.tx_bytes));
675     BX_NE2K_THIS ethdev->sendpkt(& BX_NE2K_THIS s.mem[tx_start_ofs - BX_NE2K_MEMSTART], BX_NE2K_THIS s.tx_bytes);
676 
677     // some more debug
678     if (BX_NE2K_THIS s.tx_timer_active)
679       BX_ERROR(("CR write, tx timer still active"));
680 
681     // Schedule a timer to trigger a tx-complete interrupt
682     // The number of microseconds is the bit-time / 10.
683     // The bit-time is the preamble+sfd (64 bits), the
684     // inter-frame gap (96 bits), the CRC (4 bytes), and the
685     // the number of bits in the frame (s.tx_bytes * 8).
686     //
687     bx_pc_system.activate_timer(BX_NE2K_THIS s.tx_timer_index,
688 				(64 + 96 + 4*8 + BX_NE2K_THIS s.tx_bytes*8)/10,
689 				0); // not continuous
690     BX_NE2K_THIS s.tx_timer_active = 1;
691     bx_gui->statusbar_setitem(BX_NE2K_THIS s.statusbar_id, 1, 1);
692   }
693 
694   // Linux probes for an interrupt by setting up a remote-DMA read
695   // of 0 bytes with remote-DMA completion interrupts enabled.
696   // Detect this here
697   if (BX_NE2K_THIS s.CR.rdma_cmd == 0x01 &&
698       BX_NE2K_THIS s.CR.start &&
699       BX_NE2K_THIS s.remote_bytes == 0) {
700     BX_NE2K_THIS s.ISR.rdma_done = 1;
701     if (BX_NE2K_THIS s.IMR.rdma_inte) {
702       set_irq_level(1);
703     }
704   }
705 }
706 
707 //
708 // chipmem_read/chipmem_write - access the 64K private RAM.
709 // The ne2000 memory is accessed through the data port of
710 // the asic (offset 0) after setting up a remote-DMA transfer.
711 // Both byte and word accesses are allowed.
712 // The first 16 bytes contains the MAC address at even locations,
713 // and there is 16K of buffer memory starting at 16K
714 //
715 Bit32u BX_CPP_AttrRegparmN(2)
chipmem_read(Bit32u address,unsigned int io_len)716 bx_ne2k_c::chipmem_read(Bit32u address, unsigned int io_len)
717 {
718   Bit32u retval = 0;
719 
720   if ((io_len == 2) && (address & 0x1))
721     BX_PANIC(("unaligned chipmem word read"));
722 
723   // ROM'd MAC address
724   if ((address >=0) && (address <= 31)) {
725     retval = BX_NE2K_THIS s.macaddr[address];
726     if ((io_len == 2) || (io_len == 4)) {
727       retval |= (BX_NE2K_THIS s.macaddr[address + 1] << 8);
728     }
729     if (io_len == 4) {
730       retval |= (BX_NE2K_THIS s.macaddr[address + 2] << 16);
731       retval |= (BX_NE2K_THIS s.macaddr[address + 3] << 24);
732     }
733     return (retval);
734   }
735 
736   if ((address >= BX_NE2K_MEMSTART) && (address < BX_NE2K_MEMEND)) {
737     retval = BX_NE2K_THIS s.mem[address - BX_NE2K_MEMSTART];
738     if ((io_len == 2) || (io_len == 4)) {
739       retval |= (BX_NE2K_THIS s.mem[address - BX_NE2K_MEMSTART + 1] << 8);
740     }
741     if (io_len == 4) {
742       retval |= (BX_NE2K_THIS s.mem[address - BX_NE2K_MEMSTART + 2] << 16);
743       retval |= (BX_NE2K_THIS s.mem[address - BX_NE2K_MEMSTART + 3] << 24);
744     }
745     return (retval);
746   }
747 
748   BX_DEBUG(("out-of-bounds chipmem read, %04X", address));
749 
750   return (0xff);
751 }
752 
753 void BX_CPP_AttrRegparmN(3)
chipmem_write(Bit32u address,Bit32u value,unsigned io_len)754 bx_ne2k_c::chipmem_write(Bit32u address, Bit32u value, unsigned io_len)
755 {
756   if ((io_len == 2) && (address & 0x1))
757     BX_PANIC(("unaligned chipmem word write"));
758 
759   if ((address >= BX_NE2K_MEMSTART) && (address < BX_NE2K_MEMEND)) {
760     BX_NE2K_THIS s.mem[address - BX_NE2K_MEMSTART] = value & 0xff;
761     if ((io_len == 2) || (io_len == 4)) {
762       BX_NE2K_THIS s.mem[address - BX_NE2K_MEMSTART + 1] = value >> 8;
763     }
764     if (io_len == 4) {
765       BX_NE2K_THIS s.mem[address - BX_NE2K_MEMSTART + 2] = value >> 16;
766       BX_NE2K_THIS s.mem[address - BX_NE2K_MEMSTART + 3] = value >> 24;
767     }
768   } else
769     BX_DEBUG(("out-of-bounds chipmem write, %04X", address));
770 }
771 
772 //
773 // asic_read/asic_write - This is the high 16 bytes of i/o space
774 // (the lower 16 bytes is for the DS8390). Only two locations
775 // are used: offset 0, which is used for data transfer, and
776 // offset 0xf, which is used to reset the device.
777 // The data transfer port is used to as 'external' DMA to the
778 // DS8390. The chip has to have the DMA registers set up, and
779 // after that, insw/outsw instructions can be used to move
780 // the appropriate number of bytes to/from the device.
781 //
782 Bit32u BX_CPP_AttrRegparmN(2)
asic_read(Bit32u offset,unsigned int io_len)783 bx_ne2k_c::asic_read(Bit32u offset, unsigned int io_len)
784 {
785   Bit32u retval = 0;
786 
787   switch (offset) {
788   case 0x0:  // Data register
789     //
790     // A read remote-DMA command must have been issued,
791     // and the source-address and length registers must
792     // have been initialised.
793     //
794     if (io_len > BX_NE2K_THIS s.remote_bytes) {
795       BX_ERROR(("ne2K: dma read underrun iolen=%d remote_bytes=%d",io_len,BX_NE2K_THIS s.remote_bytes));
796       //return 0;
797     }
798 
799     //BX_INFO(("ne2k read DMA: addr=%4x remote_bytes=%d",BX_NE2K_THIS s.remote_dma,BX_NE2K_THIS s.remote_bytes));
800     retval = chipmem_read(BX_NE2K_THIS s.remote_dma, io_len);
801     //
802     // The 8390 bumps the address and decreases the byte count
803     // by the selected word size after every access, not by
804     // the amount of data requested by the host (io_len).
805     //
806     if (io_len == 4) {
807       BX_NE2K_THIS s.remote_dma += io_len;
808     } else {
809       BX_NE2K_THIS s.remote_dma += ((Bit8u)BX_NE2K_THIS s.DCR.wdsize + 1);
810     }
811     if (BX_NE2K_THIS s.remote_dma == BX_NE2K_THIS s.page_stop << 8) {
812       BX_NE2K_THIS s.remote_dma = BX_NE2K_THIS s.page_start << 8;
813     }
814     // keep s.remote_bytes from underflowing
815     if (BX_NE2K_THIS s.remote_bytes > (Bit8u)BX_NE2K_THIS s.DCR.wdsize)
816       if (io_len == 4) {
817         BX_NE2K_THIS s.remote_bytes -= io_len;
818       } else {
819         BX_NE2K_THIS s.remote_bytes -= ((Bit8u)BX_NE2K_THIS s.DCR.wdsize + 1);
820       }
821     else
822       BX_NE2K_THIS s.remote_bytes = 0;
823 
824     // If all bytes have been written, signal remote-DMA complete
825     if (BX_NE2K_THIS s.remote_bytes == 0) {
826       BX_NE2K_THIS s.ISR.rdma_done = 1;
827       if (BX_NE2K_THIS s.IMR.rdma_inte) {
828         set_irq_level(1);
829       }
830     }
831     break;
832 
833   case 0xf:  // Reset register
834     BX_NE2K_THIS reset(BX_RESET_SOFTWARE);
835     break;
836 
837   default:
838     BX_INFO(("asic read invalid address %04x", (unsigned) offset));
839     break;
840   }
841 
842   return (retval);
843 }
844 
asic_write(Bit32u offset,Bit32u value,unsigned io_len)845 void bx_ne2k_c::asic_write(Bit32u offset, Bit32u value, unsigned io_len)
846 {
847   BX_DEBUG(("asic write addr=0x%02x, value=0x%04x", (unsigned) offset, (unsigned) value));
848   switch (offset) {
849   case 0x0:  // Data register - see asic_read for a description
850 
851     if ((io_len > 1) && !BX_NE2K_THIS s.DCR.wdsize) {
852       BX_PANIC(("dma write length %d on byte mode operation", io_len));
853       break;
854     }
855     if (BX_NE2K_THIS s.remote_bytes == 0) {
856       BX_ERROR(("ne2K: dma write, byte count 0"));
857     }
858 
859     chipmem_write(BX_NE2K_THIS s.remote_dma, value, io_len);
860     if (io_len == 4) {
861       BX_NE2K_THIS s.remote_dma += io_len;
862     } else {
863       BX_NE2K_THIS s.remote_dma += ((Bit8u)BX_NE2K_THIS s.DCR.wdsize + 1);
864     }
865     if (BX_NE2K_THIS s.remote_dma == BX_NE2K_THIS s.page_stop << 8) {
866       BX_NE2K_THIS s.remote_dma = BX_NE2K_THIS s.page_start << 8;
867     }
868 
869     if (io_len == 4) {
870       BX_NE2K_THIS s.remote_bytes -= io_len;
871     } else {
872       BX_NE2K_THIS s.remote_bytes -= ((Bit8u)BX_NE2K_THIS s.DCR.wdsize + 1);
873     }
874     if (BX_NE2K_THIS s.remote_bytes > BX_NE2K_MEMSIZ)
875       BX_NE2K_THIS s.remote_bytes = 0;
876 
877     // If all bytes have been written, signal remote-DMA complete
878     if (BX_NE2K_THIS s.remote_bytes == 0) {
879       BX_NE2K_THIS s.ISR.rdma_done = 1;
880       if (BX_NE2K_THIS s.IMR.rdma_inte) {
881         set_irq_level(1);
882       }
883     }
884     break;
885 
886   case 0xf:  // Reset register
887     // end of reset pulse
888     break;
889 
890   default: // this is invalid, but happens under win95 device detection
891     BX_INFO(("asic write invalid address %04x, ignoring", (unsigned) offset));
892     break;
893   }
894 }
895 
896 //
897 // page0_read/page0_write - These routines handle reads/writes to
898 // the 'zeroth' page of the DS8390 register file
899 //
page0_read(Bit32u offset,unsigned int io_len)900 Bit32u bx_ne2k_c::page0_read(Bit32u offset, unsigned int io_len)
901 {
902   Bit8u value = 0;
903 
904   if (io_len > 1) {
905     BX_ERROR(("bad length! page 0 read from register 0x%02x, len=%u", offset,
906               io_len)); /* encountered with win98 hardware probe */
907     return value;
908   }
909 
910   switch (offset) {
911   case 0x1:  // CLDA0
912     value = (BX_NE2K_THIS s.local_dma & 0xff);
913     break;
914 
915   case 0x2:  // CLDA1
916     value = (BX_NE2K_THIS s.local_dma >> 8);
917     break;
918 
919   case 0x3:  // BNRY
920     value = BX_NE2K_THIS s.bound_ptr;
921     break;
922 
923   case 0x4:  // TSR
924     value = ((BX_NE2K_THIS s.TSR.ow_coll    << 7) |
925              (BX_NE2K_THIS s.TSR.cd_hbeat   << 6) |
926              (BX_NE2K_THIS s.TSR.fifo_ur    << 5) |
927              (BX_NE2K_THIS s.TSR.no_carrier << 4) |
928              (BX_NE2K_THIS s.TSR.aborted    << 3) |
929              (BX_NE2K_THIS s.TSR.collided   << 2) |
930              (Bit8u)BX_NE2K_THIS s.TSR.tx_ok);
931     break;
932 
933   case 0x5:  // NCR
934     value = BX_NE2K_THIS s.num_coll;
935     break;
936 
937   case 0x6:  // FIFO
938     // reading FIFO is only valid in loopback mode
939     BX_ERROR(("reading FIFO not supported yet"));
940     value = BX_NE2K_THIS s.fifo;
941     break;
942 
943   case 0x7:  // ISR
944     value = ((BX_NE2K_THIS s.ISR.reset     << 7) |
945              (BX_NE2K_THIS s.ISR.rdma_done << 6) |
946              (BX_NE2K_THIS s.ISR.cnt_oflow << 5) |
947              (BX_NE2K_THIS s.ISR.overwrite << 4) |
948              (BX_NE2K_THIS s.ISR.tx_err    << 3) |
949              (BX_NE2K_THIS s.ISR.rx_err    << 2) |
950              (BX_NE2K_THIS s.ISR.pkt_tx    << 1) |
951              (Bit8u)BX_NE2K_THIS s.ISR.pkt_rx);
952     break;
953 
954   case 0x8:  // CRDA0
955     value = (BX_NE2K_THIS s.remote_dma & 0xff);
956     break;
957 
958   case 0x9:  // CRDA1
959     value = (BX_NE2K_THIS s.remote_dma >> 8);
960     break;
961 
962   case 0xa:  // reserved / RTL8029ID0
963     if (BX_NE2K_THIS s.pci_enabled) {
964       value = 0x50;
965     } else {
966       BX_INFO(("reserved read - page 0, 0xa"));
967       value = 0xff;
968     }
969     break;
970 
971   case 0xb:  // reserved / RTL8029ID1
972     if (BX_NE2K_THIS s.pci_enabled) {
973       value = 0x43;
974     } else {
975       BX_INFO(("reserved read - page 0, 0xb"));
976       value = 0xff;
977     }
978     break;
979 
980   case 0xc:  // RSR
981     value = ((BX_NE2K_THIS s.RSR.deferred    << 7) |
982              (BX_NE2K_THIS s.RSR.rx_disabled << 6) |
983              (BX_NE2K_THIS s.RSR.rx_mbit     << 5) |
984              (BX_NE2K_THIS s.RSR.rx_missed   << 4) |
985              (BX_NE2K_THIS s.RSR.fifo_or     << 3) |
986              (BX_NE2K_THIS s.RSR.bad_falign  << 2) |
987              (BX_NE2K_THIS s.RSR.bad_crc     << 1) |
988              (Bit8u)BX_NE2K_THIS s.RSR.rx_ok);
989     break;
990 
991   case 0xd:  // CNTR0
992     value = BX_NE2K_THIS s.tallycnt_0;
993     break;
994 
995   case 0xe:  // CNTR1
996     value = BX_NE2K_THIS s.tallycnt_1;
997     break;
998 
999   case 0xf:  // CNTR2
1000     value = BX_NE2K_THIS s.tallycnt_2;
1001     break;
1002 
1003   default:
1004     BX_PANIC(("page 0 register 0x%02x out of range", offset));
1005   }
1006 
1007   BX_DEBUG(("page 0 read from register 0x%02x, value=0x%02x", offset, value));
1008   return value;
1009 }
1010 
page0_write(Bit32u offset,Bit32u value,unsigned io_len)1011 void bx_ne2k_c::page0_write(Bit32u offset, Bit32u value, unsigned io_len)
1012 {
1013   Bit8u value2;
1014 
1015   // It appears to be a common practice to use outw on page0 regs...
1016 
1017   // break up outw into two outb's
1018   if (io_len == 2) {
1019     page0_write(offset, (value & 0xff), 1);
1020     if (offset < 0x0f) {
1021       page0_write(offset + 1, ((value >> 8) & 0xff), 1);
1022     }
1023     return;
1024   }
1025 
1026   BX_DEBUG(("page 0 write to register 0x%02x, value=0x%02x", offset, value));
1027 
1028   switch (offset) {
1029   case 0x1:  // PSTART
1030     BX_NE2K_THIS s.page_start = value;
1031     break;
1032 
1033   case 0x2:  // PSTOP
1034     BX_NE2K_THIS s.page_stop = value;
1035     break;
1036 
1037   case 0x3:  // BNRY
1038     BX_NE2K_THIS s.bound_ptr = value;
1039     break;
1040 
1041   case 0x4:  // TPSR
1042     BX_NE2K_THIS s.tx_page_start = value;
1043     break;
1044 
1045   case 0x5:  // TBCR0
1046     // Clear out low byte and re-insert
1047     BX_NE2K_THIS s.tx_bytes &= 0xff00;
1048     BX_NE2K_THIS s.tx_bytes |= (value & 0xff);
1049     break;
1050 
1051   case 0x6:  // TBCR1
1052     // Clear out high byte and re-insert
1053     BX_NE2K_THIS s.tx_bytes &= 0x00ff;
1054     BX_NE2K_THIS s.tx_bytes |= ((value & 0xff) << 8);
1055     break;
1056 
1057   case 0x7:  // ISR
1058     value &= 0x7f;  // clear RST bit - status-only bit
1059     // All other values are cleared if the ISR bit is 1
1060     BX_NE2K_THIS s.ISR.pkt_rx    &= !((value & 0x01) > 0);
1061     BX_NE2K_THIS s.ISR.pkt_tx    &= !((value & 0x02) > 0);
1062     BX_NE2K_THIS s.ISR.rx_err    &= !((value & 0x04) > 0);
1063     BX_NE2K_THIS s.ISR.tx_err    &= !((value & 0x08) > 0);
1064     BX_NE2K_THIS s.ISR.overwrite &= !((value & 0x10) > 0);
1065     BX_NE2K_THIS s.ISR.cnt_oflow &= !((value & 0x20) > 0);
1066     BX_NE2K_THIS s.ISR.rdma_done &= !((value & 0x40) > 0);
1067     value = ((BX_NE2K_THIS s.ISR.rdma_done << 6) |
1068              (BX_NE2K_THIS s.ISR.cnt_oflow << 5) |
1069              (BX_NE2K_THIS s.ISR.overwrite << 4) |
1070              (BX_NE2K_THIS s.ISR.tx_err    << 3) |
1071              (BX_NE2K_THIS s.ISR.rx_err    << 2) |
1072              (BX_NE2K_THIS s.ISR.pkt_tx    << 1) |
1073              (Bit8u)BX_NE2K_THIS s.ISR.pkt_rx);
1074     value &= ((BX_NE2K_THIS s.IMR.rdma_inte << 6) |
1075               (BX_NE2K_THIS s.IMR.cofl_inte << 5) |
1076               (BX_NE2K_THIS s.IMR.overw_inte << 4) |
1077               (BX_NE2K_THIS s.IMR.txerr_inte << 3) |
1078               (BX_NE2K_THIS s.IMR.rxerr_inte << 2) |
1079               (BX_NE2K_THIS s.IMR.tx_inte << 1) |
1080               (Bit8u)BX_NE2K_THIS s.IMR.rx_inte);
1081     if (value == 0)
1082       set_irq_level(0);
1083     break;
1084 
1085   case 0x8:  // RSAR0
1086     // Clear out low byte and re-insert
1087     BX_NE2K_THIS s.remote_start &= 0xff00;
1088     BX_NE2K_THIS s.remote_start |= (value & 0xff);
1089     BX_NE2K_THIS s.remote_dma = BX_NE2K_THIS s.remote_start;
1090     break;
1091 
1092   case 0x9:  // RSAR1
1093     // Clear out high byte and re-insert
1094     BX_NE2K_THIS s.remote_start &= 0x00ff;
1095     BX_NE2K_THIS s.remote_start |= ((value & 0xff) << 8);
1096     BX_NE2K_THIS s.remote_dma = BX_NE2K_THIS s.remote_start;
1097     break;
1098 
1099   case 0xa:  // RBCR0
1100     // Clear out low byte and re-insert
1101     BX_NE2K_THIS s.remote_bytes &= 0xff00;
1102     BX_NE2K_THIS s.remote_bytes |= (value & 0xff);
1103     break;
1104 
1105   case 0xb:  // RBCR1
1106     // Clear out high byte and re-insert
1107     BX_NE2K_THIS s.remote_bytes &= 0x00ff;
1108     BX_NE2K_THIS s.remote_bytes |= ((value & 0xff) << 8);
1109     break;
1110 
1111   case 0xc:  // RCR
1112     // Check if the reserved bits are set
1113     if (value & 0xc0)
1114       BX_INFO(("RCR write, reserved bits set"));
1115 
1116     // Set all other bit-fields
1117     BX_NE2K_THIS s.RCR.errors_ok = (value & 0x01) > 0;
1118     BX_NE2K_THIS s.RCR.runts_ok  = (value & 0x02) > 0;
1119     BX_NE2K_THIS s.RCR.broadcast = (value & 0x04) > 0;
1120     BX_NE2K_THIS s.RCR.multicast = (value & 0x08) > 0;
1121     BX_NE2K_THIS s.RCR.promisc   = (value & 0x10) > 0;
1122     BX_NE2K_THIS s.RCR.monitor   = (value & 0x20) > 0;
1123 
1124     // Monitor bit is a little suspicious...
1125     if (value & 0x20)
1126       BX_INFO(("RCR write, monitor bit set!"));
1127     break;
1128 
1129   case 0xd:  // TCR
1130     // Check reserved bits
1131     if (value & 0xe0)
1132       BX_ERROR(("TCR write, reserved bits set"));
1133 
1134     // Test loop mode (not supported)
1135     if (value & 0x06) {
1136       BX_NE2K_THIS s.TCR.loop_cntl = (value & 0x6) >> 1;
1137       BX_INFO(("TCR write, loop mode %d not supported", BX_NE2K_THIS s.TCR.loop_cntl));
1138     } else {
1139       BX_NE2K_THIS s.TCR.loop_cntl = 0;
1140     }
1141 
1142     // Inhibit-CRC not supported.
1143     if (value & 0x01)
1144       BX_PANIC(("TCR write, inhibit-CRC not supported"));
1145 
1146     // Auto-transmit disable very suspicious
1147     if (value & 0x08)
1148       BX_PANIC(("TCR write, auto transmit disable not supported"));
1149 
1150     // Allow collision-offset to be set, although not used
1151     BX_NE2K_THIS s.TCR.coll_prio = ((value & 0x08) > 0);
1152     break;
1153 
1154   case 0xe:  // DCR
1155     // the loopback mode is not suppported yet
1156     if (!(value & 0x08)) {
1157       BX_ERROR(("DCR write, loopback mode selected"));
1158     }
1159     // It is questionable to set longaddr and auto_rx, since they
1160     // aren't supported on the ne2000. Print a warning and continue
1161     if (value & 0x04)
1162       BX_INFO(("DCR write - LAS set ???"));
1163     if (value & 0x10)
1164       BX_INFO(("DCR write - AR set ???"));
1165 
1166     // Set other values.
1167     BX_NE2K_THIS s.DCR.wdsize   = (value & 0x01) > 0;
1168     BX_NE2K_THIS s.DCR.endian   = (value & 0x02) > 0;
1169     BX_NE2K_THIS s.DCR.longaddr = (value & 0x04) > 0; // illegal ?
1170     BX_NE2K_THIS s.DCR.loop     = (value & 0x08) > 0;
1171     BX_NE2K_THIS s.DCR.auto_rx  = (value & 0x10) > 0; // also illegal ?
1172     BX_NE2K_THIS s.DCR.fifo_size = (value & 0x50) >> 5;
1173     break;
1174 
1175   case 0xf:  // IMR
1176     // Check for reserved bit
1177     if (value & 0x80)
1178       BX_ERROR(("IMR write, reserved bit set"));
1179 
1180     // Set other values
1181     BX_NE2K_THIS s.IMR.rx_inte    = (value & 0x01) > 0;
1182     BX_NE2K_THIS s.IMR.tx_inte    = (value & 0x02) > 0;
1183     BX_NE2K_THIS s.IMR.rxerr_inte = (value & 0x04) > 0;
1184     BX_NE2K_THIS s.IMR.txerr_inte = (value & 0x08) > 0;
1185     BX_NE2K_THIS s.IMR.overw_inte = (value & 0x10) > 0;
1186     BX_NE2K_THIS s.IMR.cofl_inte  = (value & 0x20) > 0;
1187     BX_NE2K_THIS s.IMR.rdma_inte  = (value & 0x40) > 0;
1188     value2 = ((BX_NE2K_THIS s.ISR.rdma_done << 6) |
1189               (BX_NE2K_THIS s.ISR.cnt_oflow << 5) |
1190               (BX_NE2K_THIS s.ISR.overwrite << 4) |
1191               (BX_NE2K_THIS s.ISR.tx_err    << 3) |
1192               (BX_NE2K_THIS s.ISR.rx_err    << 2) |
1193               (BX_NE2K_THIS s.ISR.pkt_tx    << 1) |
1194               (Bit8u)BX_NE2K_THIS s.ISR.pkt_rx);
1195     if (((value & value2) & 0x7f) == 0) {
1196       set_irq_level(0);
1197     } else {
1198       set_irq_level(1);
1199     }
1200     break;
1201 
1202   default:
1203     BX_PANIC(("page 0 write, bad register 0x%02x", offset));
1204   }
1205 }
1206 
1207 //
1208 // page1_read/page1_write - These routines handle reads/writes to
1209 // the first page of the DS8390 register file
1210 //
page1_read(Bit32u offset,unsigned int io_len)1211 Bit32u bx_ne2k_c::page1_read(Bit32u offset, unsigned int io_len)
1212 {
1213   BX_DEBUG(("page 1 read from register 0x%02x, len=%u", offset, io_len));
1214 
1215   if (io_len > 1)
1216     BX_PANIC(("bad length! page 1 read from register 0x%02x, len=%u", offset, io_len));
1217 
1218   switch (offset) {
1219   case 0x1:  // PAR0-5
1220   case 0x2:
1221   case 0x3:
1222   case 0x4:
1223   case 0x5:
1224   case 0x6:
1225     return (BX_NE2K_THIS s.physaddr[offset - 1]);
1226     break;
1227 
1228   case 0x7:  // CURR
1229     BX_DEBUG(("returning current page: 0x%02x", (BX_NE2K_THIS s.curr_page)));
1230     return (BX_NE2K_THIS s.curr_page);
1231 
1232   case 0x8:  // MAR0-7
1233   case 0x9:
1234   case 0xa:
1235   case 0xb:
1236   case 0xc:
1237   case 0xd:
1238   case 0xe:
1239   case 0xf:
1240     return (BX_NE2K_THIS s.mchash[offset - 8]);
1241     break;
1242 
1243   default:
1244     BX_PANIC(("page 1 read register 0x%02x out of range", offset));
1245   }
1246 
1247   return (0);
1248 }
1249 
page1_write(Bit32u offset,Bit32u value,unsigned io_len)1250 void bx_ne2k_c::page1_write(Bit32u offset, Bit32u value, unsigned io_len)
1251 {
1252   BX_DEBUG(("page 1 write to register 0x%02x, len=%u, value=0x%04x", offset,
1253             io_len, value));
1254 
1255   switch (offset) {
1256   case 0x1:  // PAR0-5
1257   case 0x2:
1258   case 0x3:
1259   case 0x4:
1260   case 0x5:
1261   case 0x6:
1262     BX_NE2K_THIS s.physaddr[offset - 1] = value;
1263     if (offset == 6) {
1264       BX_INFO(("Physical address set to %02x:%02x:%02x:%02x:%02x:%02x",
1265                BX_NE2K_THIS s.physaddr[0],
1266                BX_NE2K_THIS s.physaddr[1],
1267                BX_NE2K_THIS s.physaddr[2],
1268                BX_NE2K_THIS s.physaddr[3],
1269                BX_NE2K_THIS s.physaddr[4],
1270                BX_NE2K_THIS s.physaddr[5]));
1271     }
1272     break;
1273 
1274   case 0x7:  // CURR
1275     BX_NE2K_THIS s.curr_page = value;
1276     break;
1277 
1278   case 0x8:  // MAR0-7
1279   case 0x9:
1280   case 0xa:
1281   case 0xb:
1282   case 0xc:
1283   case 0xd:
1284   case 0xe:
1285   case 0xf:
1286     BX_NE2K_THIS s.mchash[offset - 8] = value;
1287     break;
1288 
1289   default:
1290     BX_PANIC(("page 1 write register 0x%02x out of range", offset));
1291   }
1292 }
1293 
1294 //
1295 // page2_read/page2_write - These routines handle reads/writes to
1296 // the second page of the DS8390 register file
1297 //
page2_read(Bit32u offset,unsigned int io_len)1298 Bit32u bx_ne2k_c::page2_read(Bit32u offset, unsigned int io_len)
1299 {
1300   BX_DEBUG(("page 2 read from register 0x%02x, len=%u", offset, io_len));
1301 
1302   if (io_len > 1)
1303     BX_PANIC(("bad length!  page 2 read from register 0x%02x, len=%u", offset, io_len));
1304 
1305   switch (offset) {
1306   case 0x1:  // PSTART
1307     return (BX_NE2K_THIS s.page_start);
1308 
1309   case 0x2:  // PSTOP
1310     return (BX_NE2K_THIS s.page_stop);
1311 
1312   case 0x3:  // Remote Next-packet pointer
1313     return (BX_NE2K_THIS s.rempkt_ptr);
1314 
1315   case 0x4:  // TPSR
1316     return (BX_NE2K_THIS s.tx_page_start);
1317 
1318   case 0x5:  // Local Next-packet pointer
1319     return (BX_NE2K_THIS s.localpkt_ptr);
1320 
1321   case 0x6:  // Address counter (upper)
1322     return (BX_NE2K_THIS s.address_cnt >> 8);
1323 
1324   case 0x7:  // Address counter (lower)
1325     return (BX_NE2K_THIS s.address_cnt & 0xff);
1326 
1327   case 0x8:  // Reserved
1328   case 0x9:
1329   case 0xa:
1330   case 0xb:
1331     BX_ERROR(("reserved read - page 2, register 0x%02x", offset));
1332     return (0xff);
1333 
1334   case 0xc:  // RCR
1335     return ((BX_NE2K_THIS s.RCR.monitor   << 5) |
1336             (BX_NE2K_THIS s.RCR.promisc   << 4) |
1337             (BX_NE2K_THIS s.RCR.multicast << 3) |
1338             (BX_NE2K_THIS s.RCR.broadcast << 2) |
1339             (BX_NE2K_THIS s.RCR.runts_ok  << 1) |
1340             (Bit8u)BX_NE2K_THIS s.RCR.errors_ok);
1341 
1342   case 0xd:  // TCR
1343     return ((BX_NE2K_THIS s.TCR.coll_prio  << 4) |
1344             (BX_NE2K_THIS s.TCR.ext_stoptx << 3) |
1345             ((BX_NE2K_THIS s.TCR.loop_cntl & 0x3) << 1) |
1346             (Bit8u)BX_NE2K_THIS s.TCR.crc_disable);
1347 
1348   case 0xe:  // DCR
1349     return (((BX_NE2K_THIS s.DCR.fifo_size & 0x3) << 5) |
1350              (BX_NE2K_THIS s.DCR.auto_rx  << 4) |
1351              (BX_NE2K_THIS s.DCR.loop     << 3) |
1352              (BX_NE2K_THIS s.DCR.longaddr << 2) |
1353              (BX_NE2K_THIS s.DCR.endian   << 1) |
1354              (Bit8u)BX_NE2K_THIS s.DCR.wdsize);
1355 
1356   case 0xf:  // IMR
1357     return ((BX_NE2K_THIS s.IMR.rdma_inte  << 6) |
1358             (BX_NE2K_THIS s.IMR.cofl_inte  << 5) |
1359             (BX_NE2K_THIS s.IMR.overw_inte << 4) |
1360             (BX_NE2K_THIS s.IMR.txerr_inte << 3) |
1361             (BX_NE2K_THIS s.IMR.rxerr_inte << 2) |
1362             (BX_NE2K_THIS s.IMR.tx_inte    << 1) |
1363             (Bit8u)BX_NE2K_THIS s.IMR.rx_inte);
1364 
1365   default:
1366     BX_PANIC(("page 2 register 0x%02x out of range", offset));
1367   }
1368 
1369   return (0);
1370 }
1371 
page2_write(Bit32u offset,Bit32u value,unsigned io_len)1372 void bx_ne2k_c::page2_write(Bit32u offset, Bit32u value, unsigned io_len)
1373 {
1374   // Maybe all writes here should be BX_PANIC()'d, since they
1375   // affect internal operation, but let them through for now
1376   // and print a warning.
1377   BX_ERROR(("page 2 write to register 0x%02x, len=%u, value=0x%04x", offset,
1378             io_len, value));
1379 
1380   switch (offset) {
1381   case 0x1:  // CLDA0
1382     // Clear out low byte and re-insert
1383     BX_NE2K_THIS s.local_dma &= 0xff00;
1384     BX_NE2K_THIS s.local_dma |= (value & 0xff);
1385     break;
1386 
1387   case 0x2:  // CLDA1
1388     // Clear out high byte and re-insert
1389     BX_NE2K_THIS s.local_dma &= 0x00ff;
1390     BX_NE2K_THIS s.local_dma |= ((value & 0xff) << 8);
1391     break;
1392 
1393   case 0x3:  // Remote Next-pkt pointer
1394     BX_NE2K_THIS s.rempkt_ptr = value;
1395     break;
1396 
1397   case 0x4:
1398     BX_PANIC(("page 2 write to reserved register 0x04"));
1399     break;
1400 
1401   case 0x5:  // Local Next-packet pointer
1402     BX_NE2K_THIS s.localpkt_ptr = value;
1403     break;
1404 
1405   case 0x6:  // Address counter (upper)
1406     // Clear out high byte and re-insert
1407     BX_NE2K_THIS s.address_cnt &= 0x00ff;
1408     BX_NE2K_THIS s.address_cnt |= ((value & 0xff) << 8);
1409     break;
1410 
1411   case 0x7:  // Address counter (lower)
1412     // Clear out low byte and re-insert
1413     BX_NE2K_THIS s.address_cnt &= 0xff00;
1414     BX_NE2K_THIS s.address_cnt |= (value & 0xff);
1415     break;
1416 
1417   case 0x8:
1418   case 0x9:
1419   case 0xa:
1420   case 0xb:
1421   case 0xc:
1422   case 0xd:
1423   case 0xe:
1424   case 0xf:
1425     BX_PANIC(("page 2 write to reserved register 0x%02x", offset));
1426     break;
1427 
1428   default:
1429     BX_PANIC(("page 2 write, illegal register 0x%02x", offset));
1430     break;
1431   }
1432 }
1433 
1434 //
1435 // page3_read/page3_write - writes to this page are illegal
1436 //
page3_read(Bit32u offset,unsigned int io_len)1437 Bit32u bx_ne2k_c::page3_read(Bit32u offset, unsigned int io_len)
1438 {
1439   if (BX_NE2K_THIS s.pci_enabled) {
1440     switch (offset) {
1441       case 0x3:  // CONFIG0
1442         return (0);
1443       case 0x5:  // CONFIG2
1444         return (0x40);
1445       case 0x6:  // CONFIG3
1446         return (0x40);
1447       default:
1448         BX_ERROR(("page 3 read register 0x%02x attempted", offset));
1449         return (0);
1450     }
1451   } else {
1452     BX_ERROR(("page 3 read register 0x%02x attempted", offset));
1453     return (0);
1454   }
1455 }
1456 
page3_write(Bit32u offset,Bit32u value,unsigned io_len)1457 void bx_ne2k_c::page3_write(Bit32u offset, Bit32u value, unsigned io_len)
1458 {
1459   BX_ERROR(("page 3 write register 0x%02x attempted", offset));
1460 }
1461 
1462 //
1463 // tx_timer_handler/tx_timer
1464 //
tx_timer_handler(void * this_ptr)1465 void bx_ne2k_c::tx_timer_handler(void *this_ptr)
1466 {
1467   bx_ne2k_c *class_ptr = (bx_ne2k_c *) this_ptr;
1468   class_ptr->tx_timer();
1469 }
1470 
tx_timer(void)1471 void bx_ne2k_c::tx_timer(void)
1472 {
1473   BX_DEBUG(("tx_timer"));
1474   BX_NE2K_THIS s.CR.tx_packet = 0;
1475   BX_NE2K_THIS s.TSR.tx_ok = 1;
1476   BX_NE2K_THIS s.ISR.pkt_tx = 1;
1477   // Generate an interrupt if not masked
1478   if (BX_NE2K_THIS s.IMR.tx_inte) {
1479     set_irq_level(1);
1480   }
1481   BX_NE2K_THIS s.tx_timer_active = 0;
1482 }
1483 
1484 
1485 #if BX_SUPPORT_PCI
mem_read_handler(bx_phy_address addr,unsigned len,void * data,void * param)1486 bool bx_ne2k_c::mem_read_handler(bx_phy_address addr, unsigned len,
1487                                  void *data, void *param)
1488 {
1489   bx_ne2k_c *class_ptr = (bx_ne2k_c *) param;
1490 
1491   return class_ptr->mem_read(addr, len, data);
1492 }
1493 
mem_read(bx_phy_address addr,unsigned len,void * data)1494 bool bx_ne2k_c::mem_read(bx_phy_address addr, unsigned len, void *data)
1495 {
1496   Bit8u  *data_ptr;
1497 
1498   Bit32u mask = (BX_NE2K_THIS pci_rom_size - 1);
1499 #ifdef BX_LITTLE_ENDIAN
1500   data_ptr = (Bit8u *) data;
1501 #else // BX_BIG_ENDIAN
1502   data_ptr = (Bit8u *) data + (len - 1);
1503 #endif
1504   for (unsigned i = 0; i < len; i++) {
1505     if (BX_NE2K_THIS pci_conf[0x30] & 0x01) {
1506       *data_ptr = BX_NE2K_THIS pci_rom[addr & mask];
1507     } else {
1508       *data_ptr = 0xff;
1509     }
1510     addr++;
1511 #ifdef BX_LITTLE_ENDIAN
1512     data_ptr++;
1513 #else // BX_BIG_ENDIAN
1514     data_ptr--;
1515 #endif
1516   }
1517   return 1;
1518 }
1519 #endif
1520 
1521 //
1522 // read_handler/read - i/o 'catcher' function called from BOCHS
1523 // mainline when the CPU attempts a read in the i/o space registered
1524 // by this ne2000 instance
1525 //
read_handler(void * this_ptr,Bit32u address,unsigned io_len)1526 Bit32u bx_ne2k_c::read_handler(void *this_ptr, Bit32u address, unsigned io_len)
1527 {
1528   bx_ne2k_c *class_ptr = (bx_ne2k_c *) this_ptr;
1529 
1530   return class_ptr->read(address, io_len);
1531 }
1532 
read(Bit32u address,unsigned io_len)1533 Bit32u bx_ne2k_c::read(Bit32u address, unsigned io_len)
1534 {
1535   BX_DEBUG(("read addr %x, len %d", address, io_len));
1536   Bit32u retval = 0;
1537   int offset = address - BX_NE2K_THIS s.base_address;
1538 
1539   if (offset >= 0x10) {
1540     retval = asic_read(offset - 0x10, io_len);
1541   } else if (offset == 0x00) {
1542     retval = read_cr();
1543   } else {
1544     switch (BX_NE2K_THIS s.CR.pgsel) {
1545     case 0x00:
1546       retval = page0_read(offset, io_len);
1547       break;
1548 
1549     case 0x01:
1550       retval = page1_read(offset, io_len);
1551       break;
1552 
1553     case 0x02:
1554       retval = page2_read(offset, io_len);
1555       break;
1556 
1557     case 0x03:
1558       retval = page3_read(offset, io_len);
1559       break;
1560 
1561     default:
1562       BX_PANIC(("ne2K: unknown value of pgsel in read - %d",
1563 	       BX_NE2K_THIS s.CR.pgsel));
1564     }
1565   }
1566 
1567   return (retval);
1568 }
1569 
1570 //
1571 // write_handler/write - i/o 'catcher' function called from BOCHS
1572 // mainline when the CPU attempts a write in the i/o space registered
1573 // by this ne2000 instance
1574 //
write_handler(void * this_ptr,Bit32u address,Bit32u value,unsigned io_len)1575 void bx_ne2k_c::write_handler(void *this_ptr, Bit32u address, Bit32u value,
1576 			 unsigned io_len)
1577 {
1578   bx_ne2k_c *class_ptr = (bx_ne2k_c *) this_ptr;
1579   class_ptr->write(address, value, io_len);
1580 }
1581 
write(Bit32u address,Bit32u value,unsigned io_len)1582 void bx_ne2k_c::write(Bit32u address, Bit32u value, unsigned io_len)
1583 {
1584   BX_DEBUG(("write addr %x, value %x len %d", address, value, io_len));
1585   int offset = address - BX_NE2K_THIS s.base_address;
1586 
1587   //
1588   // The high 16 bytes of i/o space are for the ne2000 asic -
1589   //  the low 16 bytes are for the DS8390, with the current
1590   //  page being selected by the PS0,PS1 registers in the
1591   //  command register
1592   //
1593   if (offset >= 0x10) {
1594     asic_write(offset - 0x10, value, io_len);
1595   } else if (offset == 0x00) {
1596     write_cr(value);
1597   } else {
1598     switch (BX_NE2K_THIS s.CR.pgsel) {
1599     case 0x00:
1600       page0_write(offset, value, io_len);
1601       break;
1602 
1603     case 0x01:
1604       page1_write(offset, value, io_len);
1605       break;
1606 
1607     case 0x02:
1608       page2_write(offset, value, io_len);
1609       break;
1610 
1611     case 0x03:
1612       page3_write(offset, value, io_len);
1613       break;
1614 
1615     default:
1616       BX_PANIC(("ne2K: unknown value of pgsel in write - %d",
1617 	       BX_NE2K_THIS s.CR.pgsel));
1618     }
1619   }
1620 }
1621 
1622 
1623 /*
1624  * mcast_index() - return the 6-bit index into the multicast
1625  * table. Stolen unashamedly from FreeBSD's if_ed.c
1626  */
mcast_index(const void * dst)1627 unsigned bx_ne2k_c::mcast_index(const void *dst)
1628 {
1629 #define POLYNOMIAL 0x04c11db6
1630   Bit32u crc = 0xffffffffL;
1631   int carry, i, j;
1632   unsigned char b;
1633   unsigned char *ep = (unsigned char *) dst;
1634 
1635   for (i = 6; --i >= 0;) {
1636     b = *ep++;
1637     for (j = 8; --j >= 0;) {
1638       carry = ((crc & 0x80000000L) ? 1 : 0) ^ (b & 0x01);
1639       crc <<= 1;
1640       b >>= 1;
1641       if (carry)
1642 	crc = ((crc ^ POLYNOMIAL) | carry);
1643     }
1644   }
1645   return (crc >> 26);
1646 #undef POLYNOMIAL
1647 }
1648 
1649 /*
1650  * Callback from the eth system driver to check if the device can receive
1651  */
rx_status_handler(void * arg)1652 Bit32u bx_ne2k_c::rx_status_handler(void *arg)
1653 {
1654   bx_ne2k_c *class_ptr = (bx_ne2k_c *) arg;
1655   return class_ptr->rx_status();
1656 }
1657 
rx_status()1658 Bit32u bx_ne2k_c::rx_status()
1659 {
1660   Bit32u status = BX_NETDEV_10MBIT;
1661   if ((BX_NE2K_THIS s.CR.stop == 0) &&
1662       (BX_NE2K_THIS s.page_start != 0) &&
1663       (BX_NE2K_THIS s.DCR.loop ||
1664        (BX_NE2K_THIS s.TCR.loop_cntl == 0))) {
1665     status |= BX_NETDEV_RXREADY;
1666   }
1667   return status;
1668 }
1669 
1670 /*
1671  * Callback from the eth system driver when a frame has arrived
1672  */
rx_handler(void * arg,const void * buf,unsigned len)1673 void bx_ne2k_c::rx_handler(void *arg, const void *buf, unsigned len)
1674 {
1675     // BX_DEBUG(("rx_handler with length %d", len));
1676   bx_ne2k_c *class_ptr = (bx_ne2k_c *) arg;
1677 
1678   class_ptr->rx_frame(buf, len);
1679 }
1680 
1681 /*
1682  * rx_frame() - called by the platform-specific code when an
1683  * ethernet frame has been received. The destination address
1684  * is tested to see if it should be accepted, and if the
1685  * rx ring has enough room, it is copied into it and
1686  * the receive process is updated
1687  */
rx_frame(const void * buf,unsigned io_len)1688 void bx_ne2k_c::rx_frame(const void *buf, unsigned io_len)
1689 {
1690   int pages;
1691   int avail;
1692   unsigned idx;
1693 //int wrapped;
1694   int nextpage;
1695   unsigned char pkthdr[4];
1696   unsigned char *pktbuf = (unsigned char *) buf;
1697   unsigned char *startptr;
1698 
1699   BX_DEBUG(("rx_frame with length %d", io_len));
1700 
1701 
1702   if ((BX_NE2K_THIS s.CR.stop != 0) ||
1703       (BX_NE2K_THIS s.page_start == 0) ||
1704       (!BX_NE2K_THIS s.DCR.loop &&
1705        (BX_NE2K_THIS s.TCR.loop_cntl != 0))) {
1706 
1707     return;
1708   }
1709 
1710   // Add the pkt header + CRC to the length, and work
1711   // out how many 256-byte pages the frame would occupy
1712   pages = (io_len + 4 + 4 + 255)/256;
1713 
1714   if (BX_NE2K_THIS s.curr_page < BX_NE2K_THIS s.bound_ptr) {
1715     avail = BX_NE2K_THIS s.bound_ptr - BX_NE2K_THIS s.curr_page;
1716   } else {
1717     avail = (BX_NE2K_THIS s.page_stop - BX_NE2K_THIS s.page_start) -
1718       (BX_NE2K_THIS s.curr_page - BX_NE2K_THIS s.bound_ptr);
1719 //  wrapped = 1;
1720   }
1721 
1722   // Avoid getting into a buffer overflow condition by not attempting
1723   // to do partial receives. The emulation to handle this condition
1724   // seems particularly painful.
1725   if ((avail < pages)
1726 #if BX_NE2K_NEVER_FULL_RING
1727       || (avail == pages)
1728 #endif
1729       ) {
1730     return;
1731   }
1732 
1733   if ((io_len < 60) && !BX_NE2K_THIS s.RCR.runts_ok) {
1734     BX_DEBUG(("rejected small packet, length %d", io_len));
1735     return;
1736   }
1737 
1738   // Do address filtering if not in promiscuous mode
1739   if (! BX_NE2K_THIS s.RCR.promisc) {
1740     if (!memcmp(buf, broadcast_macaddr, 6)) {
1741       if (!BX_NE2K_THIS s.RCR.broadcast) {
1742 	return;
1743       }
1744     } else if (pktbuf[0] & 0x01) {
1745 	if (! BX_NE2K_THIS s.RCR.multicast) {
1746 	    return;
1747 	}
1748       idx = mcast_index(buf);
1749       if (!(BX_NE2K_THIS s.mchash[idx >> 3] & (1 << (idx & 0x7)))) {
1750 	return;
1751       }
1752     } else if (0 != memcmp(buf, BX_NE2K_THIS s.physaddr, 6)) {
1753       return;
1754     }
1755   } else {
1756       BX_DEBUG(("rx_frame promiscuous receive"));
1757   }
1758 
1759 //    BX_INFO(("rx_frame %d to %x:%x:%x:%x:%x:%x from %x:%x:%x:%x:%x:%x",
1760 //  	   io_len,
1761 //  	   pktbuf[0], pktbuf[1], pktbuf[2], pktbuf[3], pktbuf[4], pktbuf[5],
1762 //  	   pktbuf[6], pktbuf[7], pktbuf[8], pktbuf[9], pktbuf[10], pktbuf[11]));
1763 
1764   nextpage = BX_NE2K_THIS s.curr_page + pages;
1765   if (nextpage >= BX_NE2K_THIS s.page_stop) {
1766     nextpage -= BX_NE2K_THIS s.page_stop - BX_NE2K_THIS s.page_start;
1767   }
1768 
1769   // Setup packet header
1770   pkthdr[0] = 0;	// rx status - old behavior
1771   pkthdr[0] = 1;        // Probably better to set it all the time
1772                         // rather than set it to 0, which is clearly wrong.
1773   if (pktbuf[0] & 0x01) {
1774     pkthdr[0] |= 0x20;  // rx status += multicast packet
1775   }
1776   pkthdr[1] = nextpage;	// ptr to next packet
1777   pkthdr[2] = (io_len + 4) & 0xff;	// length-low
1778   pkthdr[3] = (io_len + 4) >> 8;	// length-hi
1779 
1780   // copy into buffer, update curpage, and signal interrupt if config'd
1781   startptr = & BX_NE2K_THIS s.mem[BX_NE2K_THIS s.curr_page * 256 -
1782 			       BX_NE2K_MEMSTART];
1783   if ((nextpage > BX_NE2K_THIS s.curr_page) ||
1784       ((BX_NE2K_THIS s.curr_page + pages) == BX_NE2K_THIS s.page_stop)) {
1785     memcpy(startptr, pkthdr, 4);
1786     memcpy(startptr + 4, buf, io_len);
1787     BX_NE2K_THIS s.curr_page = nextpage;
1788   } else {
1789     int endbytes = (BX_NE2K_THIS s.page_stop - BX_NE2K_THIS s.curr_page)
1790       * 256;
1791     memcpy(startptr, pkthdr, 4);
1792     memcpy(startptr + 4, buf, endbytes - 4);
1793     startptr = & BX_NE2K_THIS s.mem[BX_NE2K_THIS s.page_start * 256 -
1794 				 BX_NE2K_MEMSTART];
1795     memcpy(startptr, (void *)(pktbuf + endbytes - 4),
1796 	   io_len - endbytes + 8);
1797     BX_NE2K_THIS s.curr_page = nextpage;
1798   }
1799 
1800   BX_NE2K_THIS s.RSR.rx_ok = 1;
1801   BX_NE2K_THIS s.RSR.rx_mbit = ((pktbuf[0] & 0x01) > 0);
1802 
1803   BX_NE2K_THIS s.ISR.pkt_rx = 1;
1804 
1805   if (BX_NE2K_THIS s.IMR.rx_inte) {
1806     set_irq_level(1);
1807   }
1808 
1809   bx_gui->statusbar_setitem(BX_NE2K_THIS s.statusbar_id, 1);
1810 }
1811 
set_irq_level(bool level)1812 void bx_ne2k_c::set_irq_level(bool level)
1813 {
1814   if (BX_NE2K_THIS s.pci_enabled) {
1815 #if BX_SUPPORT_PCI
1816     DEV_pci_set_irq(BX_NE2K_THIS s.devfunc, BX_NE2K_THIS pci_conf[0x3d], level);
1817 #endif
1818   } else {
1819     if (level) {
1820       DEV_pic_raise_irq(BX_NE2K_THIS s.base_irq);
1821     } else {
1822       DEV_pic_lower_irq(BX_NE2K_THIS s.base_irq);
1823     }
1824   }
1825 }
1826 
1827 #if BX_SUPPORT_PCI
1828 // pci configuration space write callback handler
pci_write_handler(Bit8u address,Bit32u value,unsigned io_len)1829 void bx_ne2k_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io_len)
1830 {
1831   Bit8u value8, oldval;
1832 
1833   if ((address > 0x13) && (address < 0x30))
1834     return;
1835 
1836   BX_DEBUG_PCI_WRITE(address, value, io_len);
1837   for (unsigned i=0; i<io_len; i++) {
1838     oldval = BX_NE2K_THIS pci_conf[address+i];
1839     value8 = (value >> (i*8)) & 0xFF;
1840     switch (address+i) {
1841       case 0x04:
1842         value8 &= 0x03;
1843         break;
1844       default:
1845         value8 = oldval;
1846     }
1847     BX_NE2K_THIS pci_conf[address+i] = value8;
1848   }
1849 }
1850 
pci_bar_change_notify(void)1851 void bx_ne2k_c::pci_bar_change_notify(void)
1852 {
1853   BX_NE2K_THIS s.base_address = pci_bar[0].addr;
1854 }
1855 #endif /* BX_SUPPORT_PCI */
1856 
1857 #if BX_DEBUGGER
debug_dump(int argc,char ** argv)1858 void bx_ne2k_c::debug_dump(int argc, char **argv)
1859 {
1860   int page = -1, reg = -1;
1861 
1862   for (int arg = 0; arg < argc; arg++) {
1863     if (!strncmp(argv[arg], "page=", 5) && isdigit(argv[arg][5])) {
1864       page = atoi(&argv[arg][5]);
1865     } else if (!strncmp(argv[arg], "reg=", 4) && isdigit(argv[arg][4])) {
1866       reg = atoi(&argv[arg][4]);
1867     } else {
1868       dbg_printf("\nUnknown option: '%s'\n", argv[arg]);
1869       return;
1870     }
1871   }
1872   BX_NE2K_THIS print_info(page, reg, 0);
1873 }
1874 
1875 /*
1876  * this implements the info device 'ne2k' command in the debugger.
1877  * info device 'ne2k' - shows all registers
1878  * info device 'ne2k' 'page=N' - shows all registers in a page
1879  * info device 'ne2k' 'page=N,reg=M' - shows just one register
1880  */
1881 
1882 #define SHOW_FIELD(reg,field) do { \
1883   if (n>0 && !(n%5)) dbg_printf ("\n  "); \
1884   dbg_printf ("%s=%d ", #field, BX_NE2K_THIS s.reg.field); \
1885   n++; \
1886 } while (0);
1887 #define BX_HIGH_BYTE(x) ((0xff00 & (x)) >> 8)
1888 #define BX_LOW_BYTE(x) (0x00ff & (x))
1889 #define BX_DUPLICATE(n) if (brief && num!=n) break;
1890 
print_info(int page,int reg,int brief)1891 void bx_ne2k_c::print_info(int page, int reg, int brief)
1892 {
1893   int i;
1894   int n = 0;
1895   if (page < 0) {
1896     for (page=0; page<=2; page++)
1897       BX_NE2K_THIS print_info(page, reg, 1);
1898     // tell them how to use this command
1899     dbg_printf("\nSupported options:\n");
1900     dbg_printf("info device 'ne2k' 'page=N' - show registers in page N\n");
1901     dbg_printf("info device 'ne2k' 'page=N,reg=M' - show just one register\n");
1902     return;
1903   }
1904   if (page > 2) {
1905     dbg_printf("NE2K has only pages 0, 1, and 2.  Page %d is out of range.\n", page);
1906     return;
1907   }
1908   if (reg < 0) {
1909     dbg_printf("NE2K registers, page %d\n", page);
1910     dbg_printf("----------------------\n");
1911     for (reg=0; reg<=15; reg++)
1912       BX_NE2K_THIS print_info(page, reg, 1);
1913     dbg_printf("----------------------\n");
1914     return;
1915   }
1916   if (reg > 15) {
1917     dbg_printf("NE2K has only registers 0-15 (0x0-0xf).  Register %d is out of range.\n", reg);
1918     return;
1919   }
1920   if (!brief) {
1921     dbg_printf("NE2K Info - page %d, register 0x%02x\n", page, reg);
1922     dbg_printf("----------------------------------\n");
1923   }
1924   int num = page*0x100 + reg;
1925   switch (num) {
1926     case 0x0000:
1927     case 0x0100:
1928     case 0x0200:
1929       dbg_printf ("CR (Command register):\n  ");
1930       SHOW_FIELD(CR, stop);
1931       SHOW_FIELD(CR, start);
1932       SHOW_FIELD(CR, tx_packet);
1933       SHOW_FIELD(CR, rdma_cmd);
1934       SHOW_FIELD(CR, pgsel);
1935       dbg_printf("\n");
1936       break;
1937     case 0x0003:
1938       dbg_printf("BNRY = Boundary Pointer = 0x%02x\n", BX_NE2K_THIS s.bound_ptr);
1939       break;
1940     case 0x0004:
1941       dbg_printf("TSR (Transmit Status Register), read-only:\n  ");
1942       SHOW_FIELD(TSR, tx_ok);
1943       SHOW_FIELD(TSR, reserved);
1944       SHOW_FIELD(TSR, collided);
1945       SHOW_FIELD(TSR, aborted);
1946       SHOW_FIELD(TSR, no_carrier);
1947       SHOW_FIELD(TSR, fifo_ur);
1948       SHOW_FIELD(TSR, cd_hbeat);
1949       SHOW_FIELD(TSR, ow_coll);
1950       dbg_printf("\n");
1951       // fall through into TPSR, no break line.
1952     case 0x0204:
1953       dbg_printf("TPSR = Transmit Page Start = 0x%02x\n", BX_NE2K_THIS s.tx_page_start);
1954       break;
1955     case 0x0005:
1956     case 0x0006:  BX_DUPLICATE(0x0005);
1957       dbg_printf("NCR = Number of Collisions Register (read-only) = 0x%02x\n", BX_NE2K_THIS s.num_coll);
1958       dbg_printf("TBCR1,TBCR0 = Transmit Byte Count = %02x %02x\n",
1959           BX_HIGH_BYTE(BX_NE2K_THIS s.tx_bytes),
1960           BX_LOW_BYTE(BX_NE2K_THIS s.tx_bytes));
1961       dbg_printf("FIFO = %02x\n", BX_NE2K_THIS s.fifo);
1962       break;
1963     case 0x0007:
1964       dbg_printf("ISR (Interrupt Status Register):\n  ");
1965       SHOW_FIELD(ISR, pkt_rx);
1966       SHOW_FIELD(ISR, pkt_tx);
1967       SHOW_FIELD(ISR, rx_err);
1968       SHOW_FIELD(ISR, tx_err);
1969       SHOW_FIELD(ISR, overwrite);
1970       SHOW_FIELD(ISR, cnt_oflow);
1971       SHOW_FIELD(ISR, rdma_done);
1972       SHOW_FIELD(ISR, reset);
1973       dbg_printf("\n");
1974       break;
1975     case 0x0008:
1976     case 0x0009:  BX_DUPLICATE(0x0008);
1977       dbg_printf("CRDA1,0 = Current remote DMA address = %02x %02x\n",
1978           BX_HIGH_BYTE(BX_NE2K_THIS s.remote_dma),
1979           BX_LOW_BYTE(BX_NE2K_THIS s.remote_dma));
1980       dbg_printf("RSAR1,0 = Remote start address = %02x %02x\n",
1981           BX_HIGH_BYTE(s.remote_start),
1982           BX_LOW_BYTE(s.remote_start));
1983       break;
1984     case 0x000a:
1985     case 0x000b:  BX_DUPLICATE(0x000a);
1986       dbg_printf("RCBR1,0 = Remote byte count = %02x\n", BX_NE2K_THIS s.remote_bytes);
1987       break;
1988     case 0x000c:
1989       dbg_printf("RSR (Receive Status Register), read-only:\n  ");
1990       SHOW_FIELD(RSR, rx_ok);
1991       SHOW_FIELD(RSR, bad_crc);
1992       SHOW_FIELD(RSR, bad_falign);
1993       SHOW_FIELD(RSR, fifo_or);
1994       SHOW_FIELD(RSR, rx_missed);
1995       SHOW_FIELD(RSR, rx_mbit);
1996       SHOW_FIELD(RSR, rx_disabled);
1997       SHOW_FIELD(RSR, deferred);
1998       dbg_printf("\n");
1999       // fall through into RCR
2000     case 0x020c:
2001       dbg_printf("RCR (Receive Configuration Register):\n  ");
2002       SHOW_FIELD(RCR, errors_ok);
2003       SHOW_FIELD(RCR, runts_ok);
2004       SHOW_FIELD(RCR, broadcast);
2005       SHOW_FIELD(RCR, multicast);
2006       SHOW_FIELD(RCR, promisc);
2007       SHOW_FIELD(RCR, monitor);
2008       SHOW_FIELD(RCR, reserved);
2009       dbg_printf("\n");
2010       break;
2011     case 0x000d:
2012       dbg_printf("CNTR0 = Tally Counter 0 (Frame alignment errors) = %02x\n",
2013         BX_NE2K_THIS s.tallycnt_0);
2014       // fall through into TCR
2015     case 0x020d:
2016       dbg_printf("TCR (Transmit Configuration Register):\n  ");
2017       SHOW_FIELD(TCR, crc_disable);
2018       SHOW_FIELD(TCR, loop_cntl);
2019       SHOW_FIELD(TCR, ext_stoptx);
2020       SHOW_FIELD(TCR, coll_prio);
2021       SHOW_FIELD(TCR, reserved);
2022       dbg_printf("\n");
2023       break;
2024     case 0x000e:
2025       dbg_printf("CNTR1 = Tally Counter 1 (CRC Errors) = %02x\n",
2026         BX_NE2K_THIS s.tallycnt_1);
2027       // fall through into DCR
2028     case 0x020e:
2029       dbg_printf("DCR (Data Configuration Register):\n  ");
2030       SHOW_FIELD(DCR, wdsize);
2031       SHOW_FIELD(DCR, endian);
2032       SHOW_FIELD(DCR, longaddr);
2033       SHOW_FIELD(DCR, loop);
2034       SHOW_FIELD(DCR, auto_rx);
2035       SHOW_FIELD(DCR, fifo_size);
2036       dbg_printf("\n");
2037       break;
2038     case 0x000f:
2039       dbg_printf("CNTR2 = Tally Counter 2 (Missed Packet Errors) = %02x\n",
2040         BX_NE2K_THIS s.tallycnt_2);
2041       // fall through into IMR
2042     case 0x020f:
2043       dbg_printf("IMR (Interrupt Mask Register)\n  ");
2044       SHOW_FIELD(IMR, rx_inte);
2045       SHOW_FIELD(IMR, tx_inte);
2046       SHOW_FIELD(IMR, rxerr_inte);
2047       SHOW_FIELD(IMR, txerr_inte);
2048       SHOW_FIELD(IMR, overw_inte);
2049       SHOW_FIELD(IMR, cofl_inte);
2050       SHOW_FIELD(IMR, rdma_inte);
2051       SHOW_FIELD(IMR, reserved);
2052       dbg_printf("\n");
2053       break;
2054     case 0x0101:
2055     case 0x0102:  BX_DUPLICATE(0x0101);
2056     case 0x0103:  BX_DUPLICATE(0x0101);
2057     case 0x0104:  BX_DUPLICATE(0x0101);
2058     case 0x0105:  BX_DUPLICATE(0x0101);
2059     case 0x0106:  BX_DUPLICATE(0x0101);
2060       dbg_printf("MAC address registers are located at page 1, registers 1-6.\n");
2061       dbg_printf("The MAC address is ");
2062       for (i=0; i<=5; i++)
2063         dbg_printf("%02x%c", BX_NE2K_THIS s.physaddr[i], i<5?':' : '\n');
2064       break;
2065     case 0x0107:
2066       dbg_printf("Current page is 0x%02x\n", BX_NE2K_THIS s.curr_page);
2067       break;
2068     case 0x0108:
2069     case 0x0109:  BX_DUPLICATE(0x0108);
2070     case 0x010A:  BX_DUPLICATE(0x0108);
2071     case 0x010B:  BX_DUPLICATE(0x0108);
2072     case 0x010C:  BX_DUPLICATE(0x0108);
2073     case 0x010D:  BX_DUPLICATE(0x0108);
2074     case 0x010E:  BX_DUPLICATE(0x0108);
2075     case 0x010F:  BX_DUPLICATE(0x0108);
2076       dbg_printf("MAR0-7 (Multicast address registers 0-7) are set to:\n");
2077       for (i=0; i<8; i++) dbg_printf("%02x ", BX_NE2K_THIS s.mchash[i]);
2078       dbg_printf("\nMAR0 is listed first.\n");
2079       break;
2080     case 0x0001:
2081     case 0x0002:  BX_DUPLICATE(0x0001);
2082     case 0x0201:  BX_DUPLICATE(0x0001);
2083     case 0x0202:  BX_DUPLICATE(0x0001);
2084       dbg_printf("PSTART = Page start register = %02x\n", BX_NE2K_THIS s.page_start);
2085       dbg_printf("PSTOP = Page stop register = %02x\n", BX_NE2K_THIS s.page_stop);
2086       dbg_printf("Local DMA address = %02x %02x\n",
2087           BX_HIGH_BYTE(BX_NE2K_THIS s.local_dma),
2088           BX_LOW_BYTE(BX_NE2K_THIS s.local_dma));
2089       break;
2090     case 0x0203:
2091       dbg_printf("Remote Next Packet Pointer = %02x\n", BX_NE2K_THIS s.rempkt_ptr);
2092       break;
2093     case 0x0205:
2094       dbg_printf("Local Next Packet Pointer = %02x\n", BX_NE2K_THIS s.localpkt_ptr);
2095       break;
2096     case 0x0206:
2097     case 0x0207:  BX_DUPLICATE(0x0206);
2098       dbg_printf("Address Counter= %02x %02x\n",
2099          BX_HIGH_BYTE(BX_NE2K_THIS s.address_cnt),
2100          BX_LOW_BYTE(BX_NE2K_THIS s.address_cnt));
2101       break;
2102     case 0x0208:
2103     case 0x0209:  BX_DUPLICATE(0x0208);
2104     case 0x020A:  BX_DUPLICATE(0x0208);
2105     case 0x020B:  BX_DUPLICATE(0x0208);
2106       if (!brief) dbg_printf ("Reserved\n");
2107     case 0xffff:
2108       dbg_printf("IMR (Interrupt Mask Register):\n  ");
2109       dbg_printf("\n");
2110       break;
2111     default:
2112       dbg_printf("NE2K info: sorry, page %d register %d cannot be displayed.\n", page, reg);
2113   }
2114   if (!brief)
2115     dbg_printf("\n");
2116 }
2117 #endif
2118 
2119 #endif /* if BX_SUPPORT_NE2K */
2120