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(¶ms[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(¶ms[i][5]);
143 valid |= 0x08;
144 } else if (!strncmp(params[i], "ioaddr=", 7)) {
145 SIM->get_param_num("ioaddr", base)->set(strtoul(¶ms[i][7], NULL, 16));
146 valid |= 0x01;
147 } else if (!strncmp(params[i], "irq=", 4)) {
148 SIM->get_param_num("irq", base)->set(atol(¶ms[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