1 /////////////////////////////////////////////////////////////////////////
2 // $Id: devices.cc 14293 2021-06-27 14:50:26Z vruppert $
3 /////////////////////////////////////////////////////////////////////////
4 //
5 // Copyright (C) 2002-2021 The Bochs Project
6 //
7 // I/O port handlers API Copyright (C) 2003 by Frank Cornelis
8 //
9 // This library is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU Lesser General Public
11 // License as published by the Free Software Foundation; either
12 // version 2 of the License, or (at your option) any later version.
13 //
14 // This library is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 // Lesser General Public License for more details.
18 //
19 // You should have received a copy of the GNU Lesser General Public
20 // License along with this library; if not, write to the Free Software
21 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 //
23 /////////////////////////////////////////////////////////////////////////
24
25
26 #include "iodev.h"
27 #include "gui/keymap.h"
28
29 #include "iodev/virt_timer.h"
30 #include "iodev/slowdown_timer.h"
31 #include "iodev/sound/soundmod.h"
32 #include "iodev/network/netmod.h"
33 #include "iodev/usb/usb_common.h"
34 #include "iodev/hdimage/hdimage.h"
35
36 #define LOG_THIS bx_devices.
37
38 /* main memory size (in Kbytes)
39 * subtract 1k for extended BIOS area
40 * report only base memory, not extended mem
41 */
42 #define BASE_MEMORY_IN_K 640
43
44
45 bx_devices_c bx_devices;
46
47
48 // constructor for bx_devices_c
bx_devices_c()49 bx_devices_c::bx_devices_c()
50 {
51 put("devices", "DEV");
52
53 read_port_to_handler = NULL;
54 write_port_to_handler = NULL;
55 io_read_handlers.next = NULL;
56 io_read_handlers.handler_name = NULL;
57 io_write_handlers.next = NULL;
58 io_write_handlers.handler_name = NULL;
59 init_stubs();
60
61 for (unsigned i=0; i < BX_MAX_IRQS; i++) {
62 irq_handler_name[i] = NULL;
63 }
64 sound_device_count = 0;
65 }
66
~bx_devices_c()67 bx_devices_c::~bx_devices_c()
68 {
69 timer_handle = BX_NULL_TIMER_HANDLE;
70 bx_hdimage_ctl.exit();
71 #if BX_NETWORKING
72 bx_netmod_ctl.exit();
73 #endif
74 #if BX_SUPPORT_SOUNDLOW
75 bx_soundmod_ctl.exit();
76 #endif
77 #if BX_SUPPORT_PCIUSB
78 bx_usbdev_ctl.exit();
79 #endif
80 }
81
init_stubs()82 void bx_devices_c::init_stubs()
83 {
84 pluginCmosDevice = &stubCmos;
85 pluginDmaDevice = &stubDma;
86 pluginHardDrive = &stubHardDrive;
87 pluginPicDevice = &stubPic;
88 pluginPitDevice = &stubPit;
89 pluginSpeaker = &stubSpeaker;
90 pluginVgaDevice = &stubVga;
91 #if BX_SUPPORT_IODEBUG
92 pluginIODebug = &stubIODebug;
93 #endif
94 #if BX_SUPPORT_APIC
95 pluginIOAPIC = &stubIOAPIC;
96 #endif
97 #if BX_SUPPORT_GAMEPORT
98 pluginGameport = &stubGameport;
99 #endif
100 #if BX_SUPPORT_PCI
101 pluginPci2IsaBridge = &stubPci2Isa;
102 pluginPciIdeController = &stubPciIde;
103 pluginACPIController = &stubACPIController;
104 #endif
105 }
106
init(BX_MEM_C * newmem)107 void bx_devices_c::init(BX_MEM_C *newmem)
108 {
109 #if BX_SUPPORT_PCI
110 unsigned chipset = SIM->get_param_enum(BXPN_PCI_CHIPSET)->get();
111 unsigned max_pci_slots = BX_N_PCI_SLOTS;
112 #endif
113 unsigned i, argc;
114 const char def_name[] = "Default";
115 const char *options;
116 char *argv[16];
117
118 BX_DEBUG(("Init $Id: devices.cc 14293 2021-06-27 14:50:26Z vruppert $"));
119 mem = newmem;
120
121 /* set builtin default handlers, will be overwritten by the real default handler */
122 register_default_io_read_handler(NULL, &default_read_handler, def_name, 7);
123 io_read_handlers.next = &io_read_handlers;
124 io_read_handlers.prev = &io_read_handlers;
125 io_read_handlers.usage_count = 0; // not used with the default handler
126
127 register_default_io_write_handler(NULL, &default_write_handler, def_name, 7);
128 io_write_handlers.next = &io_write_handlers;
129 io_write_handlers.prev = &io_write_handlers;
130 io_write_handlers.usage_count = 0; // not used with the default handler
131
132 if (read_port_to_handler)
133 delete [] read_port_to_handler;
134 if (write_port_to_handler)
135 delete [] write_port_to_handler;
136 read_port_to_handler = new struct io_handler_struct *[PORTS];
137 write_port_to_handler = new struct io_handler_struct *[PORTS];
138
139 /* set handlers to the default one */
140 for (i=0; i < PORTS; i++) {
141 read_port_to_handler[i] = &io_read_handlers;
142 write_port_to_handler[i] = &io_write_handlers;
143 }
144
145 for (i=0; i < BX_MAX_IRQS; i++) {
146 delete [] irq_handler_name[i];
147 irq_handler_name[i] = NULL;
148 }
149
150 // removable devices init
151 for (i=0; i < 2; i++) {
152 bx_keyboard[i].dev = NULL;
153 bx_keyboard[i].gen_scancode = NULL;
154 bx_keyboard[i].led_mask = 0;
155 }
156 for (i = 0; i < BX_KEY_NBKEYS; i++) {
157 bx_keyboard[0].bxkey_state[i] = 0;
158 }
159 for (i=0; i < 2; i++) {
160 bx_mouse[i].dev = NULL;
161 bx_mouse[i].enq_event = NULL;
162 bx_mouse[i].enabled_changed = NULL;
163 }
164 // common mouse settings
165 mouse_captured = SIM->get_param_bool(BXPN_MOUSE_ENABLED)->get();
166 mouse_type = SIM->get_param_enum(BXPN_MOUSE_TYPE)->get();
167
168 // initialize paste feature
169 paste.buf = NULL;
170 paste.buf_len = 0;
171 paste.buf_ptr = 0;
172 paste.service = 0;
173 paste.stop = 0;
174 paste_delay_changed(SIM->get_param_num(BXPN_KBD_PASTE_DELAY)->get());
175
176 // init runtime parameters
177 SIM->get_param_num(BXPN_KBD_PASTE_DELAY)->set_handler(param_handler);
178 SIM->get_param_num(BXPN_MOUSE_ENABLED)->set_handler(param_handler);
179
180 // register as soon as possible - the devices want to have their timers !
181 bx_virt_timer.init();
182 bx_slowdown_timer.init();
183
184 #if BX_SUPPORT_SOUNDLOW
185 if (sound_device_count > 0) {
186 bx_soundmod_ctl.open_output();
187 }
188 #endif
189 // PCI logic (i440FX)
190 memset(argv, 0, sizeof(argv));
191 pci.enabled = SIM->get_param_bool(BXPN_PCI_ENABLED)->get();
192 if (pci.enabled) {
193 #if BX_SUPPORT_PCI
194 if (chipset == BX_PCI_CHIPSET_I430FX) {
195 pci.advopts = (BX_PCI_ADVOPT_NOHPET | BX_PCI_ADVOPT_NOACPI | BX_PCI_ADVOPT_NOAGP);
196 } else if (chipset == BX_PCI_CHIPSET_I440FX) {
197 pci.advopts = BX_PCI_ADVOPT_NOAGP;
198 } else {
199 pci.advopts = 0;
200 }
201 options = SIM->get_param_string(BXPN_PCI_ADV_OPTS)->getptr();
202 argc = bx_split_option_list("PCI advanced options", options, argv, 16);
203 for (i = 0; i < argc; i++) {
204 if (!strcmp(argv[i], "noacpi")) {
205 if (chipset == BX_PCI_CHIPSET_I440FX) {
206 pci.advopts |= BX_PCI_ADVOPT_NOACPI;
207 } else {
208 BX_ERROR(("Disabling ACPI not supported by PCI chipset"));
209 }
210 } else if (!strcmp(argv[i], "nohpet")) {
211 pci.advopts |= BX_PCI_ADVOPT_NOHPET;
212 } else if (!strcmp(argv[i], "noagp")) {
213 if (chipset == BX_PCI_CHIPSET_I440BX) {
214 pci.advopts |= BX_PCI_ADVOPT_NOAGP;
215 } else {
216 BX_ERROR(("Disabling AGP not supported by PCI chipset"));
217 }
218 } else {
219 BX_ERROR(("Unknown advanced PCI option '%s'", argv[i]));
220 }
221 free(argv[i]);
222 argv[i] = NULL;
223 }
224 PLUG_load_plugin(pci, PLUGTYPE_CORE);
225 PLUG_load_plugin(pci2isa, PLUGTYPE_CORE);
226 #if BX_SUPPORT_PCIUSB
227 if ((chipset == BX_PCI_CHIPSET_I440FX) ||
228 (chipset == BX_PCI_CHIPSET_I440BX)) {
229 // UHCI is a part of the PIIX3/PIIX4, so load / enable it
230 if (!PLUG_device_present("usb_uhci")) {
231 SIM->opt_plugin_ctrl("usb_uhci", 1);
232 }
233 SIM->get_param_bool(BXPN_UHCI_ENABLED)->set(1);
234 }
235 #endif
236 if ((pci.advopts & BX_PCI_ADVOPT_NOACPI) == 0) {
237 PLUG_load_plugin(acpi, PLUGTYPE_STANDARD);
238 }
239 if ((pci.advopts & BX_PCI_ADVOPT_NOHPET) == 0) {
240 PLUG_load_plugin(hpet, PLUGTYPE_STANDARD);
241 }
242 #else
243 BX_ERROR(("Bochs is not compiled with PCI support"));
244 #endif
245 }
246 PLUG_load_plugin(cmos, PLUGTYPE_CORE);
247 PLUG_load_plugin(dma, PLUGTYPE_CORE);
248 PLUG_load_plugin(pic, PLUGTYPE_CORE);
249 PLUG_load_plugin(pit, PLUGTYPE_CORE);
250 if (pluginVgaDevice == &stubVga) {
251 PLUG_load_plugin_var(BX_PLUGIN_VGA, PLUGTYPE_VGA);
252 }
253 PLUG_load_plugin(floppy, PLUGTYPE_CORE);
254
255 #if BX_SUPPORT_APIC
256 PLUG_load_plugin(ioapic, PLUGTYPE_STANDARD);
257 #endif
258 PLUG_load_plugin(keyboard, PLUGTYPE_STANDARD);
259 #if BX_SUPPORT_BUSMOUSE
260 if ((mouse_type == BX_MOUSE_TYPE_INPORT) ||
261 (mouse_type == BX_MOUSE_TYPE_BUS)) {
262 SIM->opt_plugin_ctrl("busmouse", 1);
263 }
264 #endif
265 if (is_harddrv_enabled()) {
266 PLUG_load_plugin(harddrv, PLUGTYPE_STANDARD);
267 #if BX_SUPPORT_PCI
268 if (pci.enabled) {
269 PLUG_load_plugin(pci_ide, PLUGTYPE_STANDARD);
270 }
271 #endif
272 }
273
274 // system hardware
275 register_io_read_handler(this, &read_handler, 0x0092,
276 "Port 92h System Control", 1);
277 register_io_write_handler(this, &write_handler, 0x0092,
278 "Port 92h System Control", 1);
279 #if BX_SUPPORT_PCI
280 if (pci.enabled) {
281 pci.num_pci_handlers = 0;
282
283 /* set unused elements to appropriate values */
284 for (i=0; i < BX_MAX_PCI_DEVICES; i++) {
285 pci.pci_handler[i].handler = NULL;
286 }
287
288 for (i=0; i < 0x101; i++) {
289 pci.handler_id[i] = BX_MAX_PCI_DEVICES; // not assigned
290 }
291
292 for (i=0; i < BX_N_PCI_SLOTS; i++) {
293 pci.slot_used[i] = 0; // no device connected
294 }
295
296 if (chipset == BX_PCI_CHIPSET_I440BX) {
297 pci.map_slot_to_dev = 8;
298 } else {
299 pci.map_slot_to_dev = 2;
300 }
301
302 // confAddr accepts dword i/o only
303 DEV_register_ioread_handler(this, read_handler, 0x0CF8, "PCI confAddr", 4);
304 DEV_register_iowrite_handler(this, write_handler, 0x0CF8, "PCI confAddr", 4);
305
306 for (i=0x0CFC; i<=0x0CFF; i++) {
307 DEV_register_ioread_handler(this, read_handler, i, "PCI confData", 7);
308 DEV_register_iowrite_handler(this, write_handler, i, "PCI confData", 7);
309 }
310 }
311 #endif
312
313 // misc. CMOS
314 Bit64u memory_in_k = mem->get_memory_len() / 1024;
315 Bit64u extended_memory_in_k = memory_in_k > 1024 ? (memory_in_k - 1024) : 0;
316 if (extended_memory_in_k > 0xfc00) extended_memory_in_k = 0xfc00;
317
318 DEV_cmos_set_reg(0x15, (Bit8u) BASE_MEMORY_IN_K);
319 DEV_cmos_set_reg(0x16, (Bit8u) (BASE_MEMORY_IN_K >> 8));
320 DEV_cmos_set_reg(0x17, (Bit8u) (extended_memory_in_k & 0xff));
321 DEV_cmos_set_reg(0x18, (Bit8u) ((extended_memory_in_k >> 8) & 0xff));
322 DEV_cmos_set_reg(0x30, (Bit8u) (extended_memory_in_k & 0xff));
323 DEV_cmos_set_reg(0x31, (Bit8u) ((extended_memory_in_k >> 8) & 0xff));
324
325 Bit64u extended_memory_in_64k = memory_in_k > 16384 ? (memory_in_k - 16384) / 64 : 0;
326 // Limit to 3 GB - 16 MB. PCI Memory Address Space starts at 3 GB.
327 if (extended_memory_in_64k > 0xbf00) extended_memory_in_64k = 0xbf00;
328
329 DEV_cmos_set_reg(0x34, (Bit8u) (extended_memory_in_64k & 0xff));
330 DEV_cmos_set_reg(0x35, (Bit8u) ((extended_memory_in_64k >> 8) & 0xff));
331
332 Bit64u memory_above_4gb = (mem->get_memory_len() > BX_CONST64(0x100000000)) ?
333 (mem->get_memory_len() - BX_CONST64(0x100000000)) : 0;
334 if (memory_above_4gb) {
335 DEV_cmos_set_reg(0x5b, (Bit8u)(memory_above_4gb >> 16));
336 DEV_cmos_set_reg(0x5c, (Bit8u)(memory_above_4gb >> 24));
337 DEV_cmos_set_reg(0x5d, memory_above_4gb >> 32);
338 }
339
340 options = SIM->get_param_string(BXPN_ROM_OPTIONS)->getptr();
341 argc = bx_split_option_list("ROM image options", options, argv, 16);
342 for (i = 0; i < argc; i++) {
343 if (!strcmp(argv[i], "fastboot")) {
344 DEV_cmos_set_reg(0x3f, 0x01);
345 } else {
346 BX_ERROR(("Unknown ROM image option '%s'", argv[i]));
347 }
348 free(argv[i]);
349 argv[i] = NULL;
350 }
351
352 if (timer_handle != BX_NULL_TIMER_HANDLE) {
353 timer_handle = DEV_register_timer(this, timer_handler,
354 (unsigned) BX_IODEV_HANDLER_PERIOD, 1, 1, "devices.cc");
355 }
356
357 // Clear fields for bulk IO acceleration transfers.
358 bulkIOHostAddr = 0;
359 bulkIOQuantumsRequested = 0;
360 bulkIOQuantumsTransferred = 0;
361
362 bx_init_plugins();
363
364 /* now perform checksum of CMOS memory */
365 DEV_cmos_checksum();
366
367 #if BX_SUPPORT_PCI
368 // verify PCI slot configuration
369 char devname[80];
370 const char *device;
371
372 if (pci.enabled) {
373 if ((chipset == BX_PCI_CHIPSET_I440BX) && is_agp_present()) {
374 device = SIM->get_param_enum("pci.slot.5")->get_selected();
375 if (strcmp(device, "none") && !pci.slot_used[4]) {
376 BX_PANIC(("Unknown plugin '%s' at AGP slot", device));
377 }
378 max_pci_slots = 4;
379 }
380 for (i = 0; i < max_pci_slots; i++) {
381 sprintf(devname, "pci.slot.%d", i+1);
382 device = SIM->get_param_enum(devname)->get_selected();
383 if (strcmp(device, "none") && !pci.slot_used[i]) {
384 BX_PANIC(("Unknown plugin '%s' at PCI slot #%d", device, i+1));
385 }
386 }
387 }
388 #endif
389 }
390
reset(unsigned type)391 void bx_devices_c::reset(unsigned type)
392 {
393 #if BX_SUPPORT_PCI
394 if (pci.enabled) {
395 pci.confAddr = 0;
396 }
397 #endif
398 mem->disable_smram();
399 bx_reset_plugins(type);
400 release_keys();
401 if (paste.buf != NULL) {
402 paste.stop = 1;
403 }
404 }
405
register_state()406 void bx_devices_c::register_state()
407 {
408 #if BX_SUPPORT_PCI
409 if (pci.enabled) {
410 bx_list_c *list = new bx_list_c(SIM->get_bochs_root(), "pcicore", "Generic PCI State");
411 BXRS_HEX_PARAM_FIELD(list, confAddr, pci.confAddr);
412 }
413 #endif
414 bx_virt_timer.register_state();
415 bx_plugins_register_state();
416 }
417
after_restore_state()418 void bx_devices_c::after_restore_state()
419 {
420 bx_slowdown_timer.after_restore_state();
421 bx_virt_timer.set_realtime_delay();
422 bx_plugins_after_restore_state();
423 }
424
exit()425 void bx_devices_c::exit()
426 {
427 // delete i/o handlers before unloading plugins
428 struct io_handler_struct *io_read_handler = io_read_handlers.next;
429 struct io_handler_struct *curr = NULL;
430 while (io_read_handler != &io_read_handlers) {
431 io_read_handler->prev->next = io_read_handler->next;
432 io_read_handler->next->prev = io_read_handler->prev;
433 curr = io_read_handler;
434 io_read_handler = io_read_handler->next;
435 delete [] curr->handler_name;
436 delete curr;
437 }
438 struct io_handler_struct *io_write_handler = io_write_handlers.next;
439 while (io_write_handler != &io_write_handlers) {
440 io_write_handler->prev->next = io_write_handler->next;
441 io_write_handler->next->prev = io_write_handler->prev;
442 curr = io_write_handler;
443 io_write_handler = io_write_handler->next;
444 delete [] curr->handler_name;
445 delete curr;
446 }
447
448 bx_virt_timer.setup();
449 bx_slowdown_timer.exit();
450
451 // unload device plugins
452 bx_unload_plugins();
453 // remove runtime parameter handlers
454 SIM->get_param_num(BXPN_KBD_PASTE_DELAY)->set_handler(NULL);
455 SIM->get_param_num(BXPN_MOUSE_ENABLED)->set_handler(NULL);
456 if (paste.buf != NULL) {
457 delete [] paste.buf;
458 paste.buf = NULL;
459 }
460 bx_keyboard[0].dev = NULL;
461 bx_mouse[0].dev = NULL;
462 init_stubs();
463 }
464
read_handler(void * this_ptr,Bit32u address,unsigned io_len)465 Bit32u bx_devices_c::read_handler(void *this_ptr, Bit32u address, unsigned io_len)
466 {
467 #if !BX_USE_DEV_SMF
468 bx_devices_c *class_ptr = (bx_devices_c *) this_ptr;
469 return class_ptr->read(address, io_len);
470 }
471
read(Bit32u address,unsigned io_len)472 Bit32u bx_devices_c::read(Bit32u address, unsigned io_len)
473 {
474 #else
475 UNUSED(this_ptr);
476 #endif // !BX_USE_DEV_SMF
477
478 switch (address) {
479 case 0x0092:
480 BX_DEBUG(("port92h read partially supported!!!"));
481 BX_DEBUG((" returning %02x", (unsigned) (BX_GET_ENABLE_A20() << 1)));
482 return(BX_GET_ENABLE_A20() << 1);
483 #if BX_SUPPORT_PCI
484 case 0x0CF8:
485 return BX_DEV_THIS pci.confAddr;
486 case 0x0CFC:
487 case 0x0CFD:
488 case 0x0CFE:
489 case 0x0CFF:
490 {
491 Bit32u handle, retval = 0xffffffff;
492 Bit8u regnum;
493 Bit16u bus_devfunc;
494
495 if ((BX_DEV_THIS pci.confAddr & 0x80fe0000) == 0x80000000) {
496 bus_devfunc = (BX_DEV_THIS pci.confAddr >> 8) & 0x1ff;
497 regnum = (BX_DEV_THIS pci.confAddr & 0xfc) + (address & 0x03);
498 if (bus_devfunc <= 0x100) {
499 handle = BX_DEV_THIS pci.handler_id[bus_devfunc];
500 if ((io_len <= 4) && (handle < BX_MAX_PCI_DEVICES)) {
501 retval = BX_DEV_THIS pci.pci_handler[handle].handler->pci_read_handler(regnum, io_len);
502 }
503 }
504 }
505 return retval;
506 }
507 #endif
508 }
509
510 BX_PANIC(("unsupported IO read to port 0x%x", (unsigned) address));
511 return(0xffffffff);
512 }
513
write_handler(void * this_ptr,Bit32u address,Bit32u value,unsigned io_len)514 void bx_devices_c::write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len)
515 {
516 #if !BX_USE_DEV_SMF
517 bx_devices_c *class_ptr = (bx_devices_c *) this_ptr;
518 class_ptr->write(address, value, io_len);
519 }
520
write(Bit32u address,Bit32u value,unsigned io_len)521 void bx_devices_c::write(Bit32u address, Bit32u value, unsigned io_len)
522 {
523 #else
524 UNUSED(this_ptr);
525 #endif // !BX_USE_DEV_SMF
526 #if BX_SUPPORT_PCI
527 Bit8u bus, devfunc, handle;
528 Bit16u bus_devfunc;
529 bx_pci_device_c *dev = NULL;
530 #endif
531
532 switch (address) {
533 case 0x0092:
534 BX_DEBUG(("port92h write of %02x partially supported!!!", (unsigned) value));
535 BX_DEBUG(("A20: set_enable_a20() called"));
536 BX_SET_ENABLE_A20((value & 0x02) >> 1);
537 BX_DEBUG(("A20: now %u", (unsigned) BX_GET_ENABLE_A20()));
538 if (value & 0x01) { /* high speed reset */
539 BX_INFO(("iowrite to port0x92 : reset resquested"));
540 bx_pc_system.Reset(BX_RESET_SOFTWARE);
541 }
542 break;
543 #if BX_SUPPORT_PCI
544 case 0xCF8:
545 BX_DEV_THIS pci.confAddr = value;
546 if ((value & 0x80000000) == 0x80000000) {
547 bus = (BX_DEV_THIS pci.confAddr >> 16) & 0xff;
548 devfunc = (BX_DEV_THIS pci.confAddr >> 8) & 0xff;
549 bus_devfunc = (bus << 8) | devfunc;
550 if (bus_devfunc <= 0x100) {
551 handle = BX_DEV_THIS pci.handler_id[bus_devfunc];
552 if (handle != BX_MAX_PCI_DEVICES) {
553 dev = BX_DEV_THIS pci.pci_handler[handle].handler;
554 }
555 }
556 if ((bus == 0) && (devfunc == 0x00)) {
557 BX_DEBUG(("%s register 0x%02x selected", dev->get_name(), value & 0xfc));
558 } else if (dev != NULL) {
559 BX_DEBUG(("PCI: request for bus %d device %d function %d (%s)", bus,
560 (devfunc >> 3), devfunc & 0x07, dev->get_name()));
561 } else if (bus == 1) {
562 BX_DEBUG(("PCI: request for AGP bus device %d function %d", (devfunc >> 3),
563 devfunc & 0x07));
564 } else {
565 BX_DEBUG(("PCI: request for bus %d device %d function %d", bus,
566 (devfunc >> 3), devfunc & 0x07));
567 }
568 }
569 break;
570
571 case 0xCFC:
572 case 0xCFD:
573 case 0xCFE:
574 case 0xCFF:
575 if ((BX_DEV_THIS pci.confAddr & 0x80fe0000) == 0x80000000) {
576 bus_devfunc = (BX_DEV_THIS pci.confAddr >> 8) & 0x1ff;
577 Bit8u regnum = (BX_DEV_THIS pci.confAddr & 0xfc) + (address & 0x03);
578 if (bus_devfunc <= 0x100) {
579 handle = BX_DEV_THIS pci.handler_id[bus_devfunc];
580 if ((io_len <= 4) && (handle < BX_MAX_PCI_DEVICES)) {
581 BX_DEV_THIS pci.pci_handler[handle].handler->pci_write_handler_common(regnum, value, io_len);
582 }
583 }
584 }
585 break;
586 #endif
587 default:
588 BX_PANIC(("IO write to port 0x%x", (unsigned) address));
589 }
590 }
591
592 // This defines the builtin default read handler,
593 // so Bochs does not segfault if unmapped is not loaded
default_read_handler(void * this_ptr,Bit32u address,unsigned io_len)594 Bit32u bx_devices_c::default_read_handler(void *this_ptr, Bit32u address, unsigned io_len)
595 {
596 UNUSED(this_ptr);
597 return 0xffffffff;
598 }
599
600 // This defines the builtin default write handler,
601 // so Bochs does not segfault if unmapped is not loaded
default_write_handler(void * this_ptr,Bit32u address,Bit32u value,unsigned io_len)602 void bx_devices_c::default_write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len)
603 {
604 UNUSED(this_ptr);
605 }
606
timer_handler(void * this_ptr)607 void bx_devices_c::timer_handler(void *this_ptr)
608 {
609 bx_devices_c *class_ptr = (bx_devices_c *) this_ptr;
610 class_ptr->timer();
611 }
612
timer()613 void bx_devices_c::timer()
614 {
615 if (++paste.counter >= paste.delay) {
616 // after the paste delay, consider adding moving more chars
617 // from the paste buffer to the keyboard buffer.
618 service_paste_buf();
619 paste.counter = 0;
620 }
621 SIM->periodic();
622 if (!bx_pc_system.kill_bochs_request)
623 bx_gui->handle_events();
624 }
625
register_irq(unsigned irq,const char * name)626 bool bx_devices_c::register_irq(unsigned irq, const char *name)
627 {
628 if (irq >= BX_MAX_IRQS) {
629 BX_PANIC(("IO device %s registered with IRQ=%d above %u",
630 name, irq, (unsigned) BX_MAX_IRQS-1));
631 return 0;
632 }
633 if (irq_handler_name[irq]) {
634 BX_PANIC(("IRQ %u conflict, %s with %s", irq, irq_handler_name[irq], name));
635 return 0;
636 }
637 irq_handler_name[irq] = new char[strlen(name)+1];
638 strcpy(irq_handler_name[irq], name);
639 return 1;
640 }
641
unregister_irq(unsigned irq,const char * name)642 bool bx_devices_c::unregister_irq(unsigned irq, const char *name)
643 {
644 if (irq >= BX_MAX_IRQS) {
645 BX_PANIC(("IO device %s tried to unregister IRQ %d above %u",
646 name, irq, (unsigned) BX_MAX_IRQS-1));
647 return 0;
648 }
649 if (!irq_handler_name[irq]) {
650 BX_INFO(("IO device %s tried to unregister IRQ %d, not registered",
651 name, irq));
652 return 0;
653 }
654
655 if (strcmp(irq_handler_name[irq], name)) {
656 BX_INFO(("IRQ %u not registered to %s but to %s", irq,
657 name, irq_handler_name[irq]));
658 return 0;
659 }
660 delete [] irq_handler_name[irq];
661 irq_handler_name[irq] = NULL;
662 return 1;
663 }
664
register_io_read_handler(void * this_ptr,bx_read_handler_t f,Bit32u addr,const char * name,Bit8u mask)665 bool bx_devices_c::register_io_read_handler(void *this_ptr, bx_read_handler_t f,
666 Bit32u addr, const char *name, Bit8u mask)
667 {
668 addr &= 0xffff;
669
670 if (!f)
671 return 0;
672
673 /* first check if the port already has a handlers != the default handler */
674 if (read_port_to_handler[addr] &&
675 read_port_to_handler[addr] != &io_read_handlers) { // the default
676 BX_ERROR(("IO device address conflict(read) at IO address %Xh",
677 (unsigned) addr));
678 BX_ERROR((" conflicting devices: %s & %s",
679 read_port_to_handler[addr]->handler_name, name));
680 return 0;
681 }
682
683 /* first find existing handle for function or create new one */
684 struct io_handler_struct *curr = &io_read_handlers;
685 struct io_handler_struct *io_read_handler = NULL;
686 do {
687 if (curr->funct == f &&
688 curr->mask == mask &&
689 curr->this_ptr == this_ptr &&
690 !strcmp(curr->handler_name, name)) { // really want the same name too
691 io_read_handler = curr;
692 break;
693 }
694 curr = curr->next;
695 } while (curr->next != &io_read_handlers);
696
697 if (!io_read_handler) {
698 io_read_handler = new struct io_handler_struct;
699 io_read_handler->funct = (void *)f;
700 io_read_handler->this_ptr = this_ptr;
701 io_read_handler->handler_name = new char[strlen(name)+1];
702 strcpy(io_read_handler->handler_name, name);
703 io_read_handler->mask = mask;
704 io_read_handler->usage_count = 0;
705 // add the handler to the double linked list of handlers
706 io_read_handlers.prev->next = io_read_handler;
707 io_read_handler->next = &io_read_handlers;
708 io_read_handler->prev = io_read_handlers.prev;
709 io_read_handlers.prev = io_read_handler;
710 }
711
712 io_read_handler->usage_count++;
713 read_port_to_handler[addr] = io_read_handler;
714 return 1; // address mapped successfully
715 }
716
register_io_write_handler(void * this_ptr,bx_write_handler_t f,Bit32u addr,const char * name,Bit8u mask)717 bool bx_devices_c::register_io_write_handler(void *this_ptr, bx_write_handler_t f,
718 Bit32u addr, const char *name, Bit8u mask)
719 {
720 addr &= 0xffff;
721
722 if (!f)
723 return 0;
724
725 /* first check if the port already has a handlers != the default handler */
726 if (write_port_to_handler[addr] &&
727 write_port_to_handler[addr] != &io_write_handlers) { // the default
728 BX_ERROR(("IO device address conflict(write) at IO address %Xh",
729 (unsigned) addr));
730 BX_ERROR((" conflicting devices: %s & %s",
731 write_port_to_handler[addr]->handler_name, name));
732 return 0;
733 }
734
735 /* first find existing handle for function or create new one */
736 struct io_handler_struct *curr = &io_write_handlers;
737 struct io_handler_struct *io_write_handler = NULL;
738 do {
739 if (curr->funct == f &&
740 curr->mask == mask &&
741 curr->this_ptr == this_ptr &&
742 !strcmp(curr->handler_name, name)) { // really want the same name too
743 io_write_handler = curr;
744 break;
745 }
746 curr = curr->next;
747 } while (curr->next != &io_write_handlers);
748
749 if (!io_write_handler) {
750 io_write_handler = new struct io_handler_struct;
751 io_write_handler->funct = (void *)f;
752 io_write_handler->this_ptr = this_ptr;
753 io_write_handler->handler_name = new char[strlen(name)+1];
754 strcpy(io_write_handler->handler_name, name);
755 io_write_handler->mask = mask;
756 io_write_handler->usage_count = 0;
757 // add the handler to the double linked list of handlers
758 io_write_handlers.prev->next = io_write_handler;
759 io_write_handler->next = &io_write_handlers;
760 io_write_handler->prev = io_write_handlers.prev;
761 io_write_handlers.prev = io_write_handler;
762 }
763
764 io_write_handler->usage_count++;
765 write_port_to_handler[addr] = io_write_handler;
766 return 1; // address mapped successfully
767 }
768
register_io_read_handler_range(void * this_ptr,bx_read_handler_t f,Bit32u begin_addr,Bit32u end_addr,const char * name,Bit8u mask)769 bool bx_devices_c::register_io_read_handler_range(void *this_ptr, bx_read_handler_t f,
770 Bit32u begin_addr, Bit32u end_addr,
771 const char *name, Bit8u mask)
772 {
773 Bit32u addr;
774 begin_addr &= 0xffff;
775 end_addr &= 0xffff;
776
777 if (end_addr < begin_addr) {
778 BX_ERROR(("!!! end_addr < begin_addr !!!"));
779 return 0;
780 }
781
782 if (!f) {
783 BX_ERROR(("!!! f == NULL !!!"));
784 return 0;
785 }
786
787 /* first check if the port already has a handlers != the default handler */
788 for (addr = begin_addr; addr <= end_addr; addr++)
789 if (read_port_to_handler[addr] &&
790 read_port_to_handler[addr] != &io_read_handlers) { // the default
791 BX_ERROR(("IO device address conflict(read) at IO address %Xh",
792 (unsigned) addr));
793 BX_ERROR((" conflicting devices: %s & %s",
794 read_port_to_handler[addr]->handler_name, name));
795 return 0;
796 }
797
798 /* first find existing handle for function or create new one */
799 struct io_handler_struct *curr = &io_read_handlers;
800 struct io_handler_struct *io_read_handler = NULL;
801 do {
802 if (curr->funct == f &&
803 curr->mask == mask &&
804 curr->this_ptr == this_ptr &&
805 !strcmp(curr->handler_name, name)) {
806 io_read_handler = curr;
807 break;
808 }
809 curr = curr->next;
810 } while (curr->next != &io_read_handlers);
811
812 if (!io_read_handler) {
813 io_read_handler = new struct io_handler_struct;
814 io_read_handler->funct = (void *)f;
815 io_read_handler->this_ptr = this_ptr;
816 io_read_handler->handler_name = new char[strlen(name)+1];
817 strcpy(io_read_handler->handler_name, name);
818 io_read_handler->mask = mask;
819 io_read_handler->usage_count = 0;
820 // add the handler to the double linked list of handlers
821 io_read_handlers.prev->next = io_read_handler;
822 io_read_handler->next = &io_read_handlers;
823 io_read_handler->prev = io_read_handlers.prev;
824 io_read_handlers.prev = io_read_handler;
825 }
826
827 io_read_handler->usage_count += end_addr - begin_addr + 1;
828 for (addr = begin_addr; addr <= end_addr; addr++)
829 read_port_to_handler[addr] = io_read_handler;
830 return 1; // address mapped successfully
831 }
832
register_io_write_handler_range(void * this_ptr,bx_write_handler_t f,Bit32u begin_addr,Bit32u end_addr,const char * name,Bit8u mask)833 bool bx_devices_c::register_io_write_handler_range(void *this_ptr, bx_write_handler_t f,
834 Bit32u begin_addr, Bit32u end_addr,
835 const char *name, Bit8u mask)
836 {
837 Bit32u addr;
838 begin_addr &= 0xffff;
839 end_addr &= 0xffff;
840
841 if (end_addr < begin_addr) {
842 BX_ERROR(("!!! end_addr < begin_addr !!!"));
843 return 0;
844 }
845
846 if (!f) {
847 BX_ERROR(("!!! f == NULL !!!"));
848 return 0;
849 }
850
851 /* first check if the port already has a handlers != the default handler */
852 for (addr = begin_addr; addr <= end_addr; addr++)
853 if (write_port_to_handler[addr] &&
854 write_port_to_handler[addr] != &io_write_handlers) { // the default
855 BX_ERROR(("IO device address conflict(read) at IO address %Xh",
856 (unsigned) addr));
857 BX_ERROR((" conflicting devices: %s & %s",
858 write_port_to_handler[addr]->handler_name, name));
859 return 0;
860 }
861
862 /* first find existing handle for function or create new one */
863 struct io_handler_struct *curr = &io_write_handlers;
864 struct io_handler_struct *io_write_handler = NULL;
865 do {
866 if (curr->funct == f &&
867 curr->mask == mask &&
868 curr->this_ptr == this_ptr &&
869 !strcmp(curr->handler_name, name)) {
870 io_write_handler = curr;
871 break;
872 }
873 curr = curr->next;
874 } while (curr->next != &io_write_handlers);
875
876 if (!io_write_handler) {
877 io_write_handler = new struct io_handler_struct;
878 io_write_handler->funct = (void *)f;
879 io_write_handler->this_ptr = this_ptr;
880 io_write_handler->handler_name = new char[strlen(name)+1];
881 strcpy(io_write_handler->handler_name, name);
882 io_write_handler->mask = mask;
883 io_write_handler->usage_count = 0;
884 // add the handler to the double linked list of handlers
885 io_write_handlers.prev->next = io_write_handler;
886 io_write_handler->next = &io_write_handlers;
887 io_write_handler->prev = io_write_handlers.prev;
888 io_write_handlers.prev = io_write_handler;
889 }
890
891 io_write_handler->usage_count += end_addr - begin_addr + 1;
892 for (addr = begin_addr; addr <= end_addr; addr++)
893 write_port_to_handler[addr] = io_write_handler;
894 return 1; // address mapped successfully
895 }
896
897
898 // Registration of default handlers (mainly be the unmapped device)
register_default_io_read_handler(void * this_ptr,bx_read_handler_t f,const char * name,Bit8u mask)899 bool bx_devices_c::register_default_io_read_handler(void *this_ptr, bx_read_handler_t f,
900 const char *name, Bit8u mask)
901 {
902 io_read_handlers.funct = (void *)f;
903 io_read_handlers.this_ptr = this_ptr;
904 if (io_read_handlers.handler_name) {
905 delete [] io_read_handlers.handler_name;
906 }
907 io_read_handlers.handler_name = new char[strlen(name)+1];
908 strcpy(io_read_handlers.handler_name, name);
909 io_read_handlers.mask = mask;
910
911 return 1;
912 }
913
register_default_io_write_handler(void * this_ptr,bx_write_handler_t f,const char * name,Bit8u mask)914 bool bx_devices_c::register_default_io_write_handler(void *this_ptr, bx_write_handler_t f,
915 const char *name, Bit8u mask)
916 {
917 io_write_handlers.funct = (void *)f;
918 io_write_handlers.this_ptr = this_ptr;
919 if (io_write_handlers.handler_name) {
920 delete [] io_write_handlers.handler_name;
921 }
922 io_write_handlers.handler_name = new char[strlen(name)+1];
923 strcpy(io_write_handlers.handler_name, name);
924 io_write_handlers.mask = mask;
925
926 return 1;
927 }
928
unregister_io_read_handler(void * this_ptr,bx_read_handler_t f,Bit32u addr,Bit8u mask)929 bool bx_devices_c::unregister_io_read_handler(void *this_ptr, bx_read_handler_t f,
930 Bit32u addr, Bit8u mask)
931 {
932 addr &= 0xffff;
933
934 struct io_handler_struct *io_read_handler = read_port_to_handler[addr];
935
936 //BX_INFO(("Unregistering I/O read handler at %#x", addr));
937
938 if (!io_read_handler) {
939 BX_ERROR((">>> NO IO_READ_HANDLER <<<"));
940 return 0;
941 }
942
943 if (io_read_handler == &io_read_handlers) {
944 BX_ERROR((">>> CANNOT UNREGISTER THE DEFAULT IO_READ_HANDLER <<<"));
945 return 0; // cannot unregister the default handler
946 }
947
948 if (io_read_handler->funct != f) {
949 BX_ERROR((">>> NOT THE SAME IO_READ_HANDLER FUNC <<<"));
950 return 0;
951 }
952
953 if (io_read_handler->this_ptr != this_ptr) {
954 BX_ERROR((">>> NOT THE SAME IO_READ_HANDLER THIS_PTR <<<"));
955 return 0;
956 }
957
958 if (io_read_handler->mask != mask) {
959 BX_ERROR((">>> NOT THE SAME IO_READ_HANDLER MASK <<<"));
960 return 0;
961 }
962
963 read_port_to_handler[addr] = &io_read_handlers; // reset to default
964 io_read_handler->usage_count--;
965
966 if (!io_read_handler->usage_count) { // kill this handler entry
967 io_read_handler->prev->next = io_read_handler->next;
968 io_read_handler->next->prev = io_read_handler->prev;
969 delete [] io_read_handler->handler_name;
970 delete io_read_handler;
971 }
972 return 1;
973 }
974
unregister_io_write_handler(void * this_ptr,bx_write_handler_t f,Bit32u addr,Bit8u mask)975 bool bx_devices_c::unregister_io_write_handler(void *this_ptr, bx_write_handler_t f,
976 Bit32u addr, Bit8u mask)
977 {
978 addr &= 0xffff;
979
980 struct io_handler_struct *io_write_handler = write_port_to_handler[addr];
981
982 if (!io_write_handler)
983 return 0;
984
985 if (io_write_handler == &io_write_handlers)
986 return 0; // cannot unregister the default handler
987
988 if (io_write_handler->funct != f)
989 return 0;
990
991 if (io_write_handler->this_ptr != this_ptr)
992 return 0;
993
994 if (io_write_handler->mask != mask)
995 return 0;
996
997 write_port_to_handler[addr] = &io_write_handlers; // reset to default
998 io_write_handler->usage_count--;
999
1000 if (!io_write_handler->usage_count) { // kill this handler entry
1001 io_write_handler->prev->next = io_write_handler->next;
1002 io_write_handler->next->prev = io_write_handler->prev;
1003 delete [] io_write_handler->handler_name;
1004 delete io_write_handler;
1005 }
1006 return 1;
1007 }
1008
unregister_io_read_handler_range(void * this_ptr,bx_read_handler_t f,Bit32u begin,Bit32u end,Bit8u mask)1009 bool bx_devices_c::unregister_io_read_handler_range(void *this_ptr, bx_read_handler_t f,
1010 Bit32u begin, Bit32u end, Bit8u mask)
1011 {
1012 begin &= 0xffff;
1013 end &= 0xffff;
1014 Bit32u addr;
1015 bool ret = 1;
1016
1017 /*
1018 * the easy way this time
1019 */
1020 for (addr = begin; addr <= end; addr++)
1021 if (!unregister_io_read_handler(this_ptr, f, addr, mask))
1022 ret = 0;
1023
1024 return ret;
1025 }
1026
unregister_io_write_handler_range(void * this_ptr,bx_write_handler_t f,Bit32u begin,Bit32u end,Bit8u mask)1027 bool bx_devices_c::unregister_io_write_handler_range(void *this_ptr, bx_write_handler_t f,
1028 Bit32u begin, Bit32u end, Bit8u mask)
1029 {
1030 begin &= 0xffff;
1031 end &= 0xffff;
1032 Bit32u addr;
1033 bool ret = 1;
1034
1035 /*
1036 * the easy way this time
1037 */
1038 for (addr = begin; addr <= end; addr++)
1039 if (!unregister_io_write_handler(this_ptr, f, addr, mask))
1040 ret = 0;
1041
1042 return ret;
1043 }
1044
1045
1046 /*
1047 * Read a byte of data from the IO memory address space
1048 */
1049
1050 Bit32u BX_CPP_AttrRegparmN(2)
inp(Bit16u addr,unsigned io_len)1051 bx_devices_c::inp(Bit16u addr, unsigned io_len)
1052 {
1053 struct io_handler_struct *io_read_handler;
1054 Bit32u ret;
1055
1056 BX_INSTR_INP(addr, io_len);
1057
1058 io_read_handler = read_port_to_handler[addr];
1059 if (io_read_handler->mask & io_len) {
1060 ret = ((bx_read_handler_t)io_read_handler->funct)(io_read_handler->this_ptr, (Bit32u)addr, io_len);
1061 } else {
1062 switch (io_len) {
1063 case 1: ret = 0xff; break;
1064 case 2: ret = 0xffff; break;
1065 default: ret = 0xffffffff; break;
1066 }
1067 if (addr != 0x0cf8) { // don't flood the logfile when probing PCI
1068 BX_ERROR(("read from port 0x%04x with len %d returns 0x%x", addr, io_len, ret));
1069 }
1070 }
1071
1072 BX_INSTR_INP2(addr, io_len, ret);
1073 BX_DBG_IO_REPORT(addr, io_len, BX_READ, ret);
1074
1075 return(ret);
1076 }
1077
1078
1079 /*
1080 * Write a byte of data to the IO memory address space.
1081 */
1082
1083 void BX_CPP_AttrRegparmN(3)
outp(Bit16u addr,Bit32u value,unsigned io_len)1084 bx_devices_c::outp(Bit16u addr, Bit32u value, unsigned io_len)
1085 {
1086 struct io_handler_struct *io_write_handler;
1087
1088 BX_INSTR_OUTP(addr, io_len, value);
1089 BX_DBG_IO_REPORT(addr, io_len, BX_WRITE, value);
1090
1091 io_write_handler = write_port_to_handler[addr];
1092 if (io_write_handler->mask & io_len) {
1093 ((bx_write_handler_t)io_write_handler->funct)(io_write_handler->this_ptr, (Bit32u)addr, value, io_len);
1094 } else if (addr != 0x0cf8) { // don't flood the logfile when probing PCI
1095 BX_ERROR(("write to port 0x%04x with len %d ignored", addr, io_len));
1096 }
1097 }
1098
is_harddrv_enabled(void)1099 bool bx_devices_c::is_harddrv_enabled(void)
1100 {
1101 char pname[24];
1102
1103 for (int i=0; i<BX_MAX_ATA_CHANNEL; i++) {
1104 sprintf(pname, "ata.%d.resources.enabled", i);
1105 if (SIM->get_param_bool(pname)->get())
1106 return 1;
1107 }
1108 return 0;
1109 }
1110
is_agp_present(void)1111 bool bx_devices_c::is_agp_present(void)
1112 {
1113 #if BX_SUPPORT_PCI
1114 return (pci.enabled && ((pci.advopts & BX_PCI_ADVOPT_NOAGP) == 0));
1115 #else
1116 return 0;
1117 #endif
1118 }
1119
add_sound_device(void)1120 void bx_devices_c::add_sound_device(void)
1121 {
1122 sound_device_count++;
1123 }
1124
remove_sound_device(void)1125 void bx_devices_c::remove_sound_device(void)
1126 {
1127 sound_device_count--;
1128 }
1129
1130 // removable keyboard/mouse registration
register_default_keyboard(void * dev,bx_kbd_gen_scancode_t kbd_gen_scancode,bx_kbd_get_elements_t kbd_get_elements)1131 void bx_devices_c::register_default_keyboard(void *dev, bx_kbd_gen_scancode_t kbd_gen_scancode,
1132 bx_kbd_get_elements_t kbd_get_elements)
1133 {
1134 if (bx_keyboard[0].dev == NULL) {
1135 bx_keyboard[0].dev = dev;
1136 bx_keyboard[0].gen_scancode = kbd_gen_scancode;
1137 bx_keyboard[0].get_elements = kbd_get_elements;
1138 bx_keyboard[0].led_mask = BX_KBD_LED_MASK_ALL;
1139 // add keyboard LEDs to the statusbar
1140 statusbar_id[BX_KBD_LED_NUM] = bx_gui->register_statusitem("NUM");
1141 statusbar_id[BX_KBD_LED_CAPS] = bx_gui->register_statusitem("CAPS");
1142 statusbar_id[BX_KBD_LED_SCRL] = bx_gui->register_statusitem("SCRL");
1143 }
1144 }
1145
register_removable_keyboard(void * dev,bx_kbd_gen_scancode_t kbd_gen_scancode,bx_kbd_get_elements_t kbd_get_elements,Bit8u led_mask)1146 void bx_devices_c::register_removable_keyboard(void *dev, bx_kbd_gen_scancode_t kbd_gen_scancode,
1147 bx_kbd_get_elements_t kbd_get_elements,
1148 Bit8u led_mask)
1149 {
1150 if (bx_keyboard[1].dev == NULL) {
1151 bx_keyboard[1].dev = dev;
1152 bx_keyboard[1].gen_scancode = kbd_gen_scancode;
1153 bx_keyboard[1].get_elements = kbd_get_elements;
1154 bx_keyboard[0].led_mask &= ~led_mask;
1155 bx_keyboard[1].led_mask = led_mask;
1156 }
1157 }
1158
unregister_removable_keyboard(void * dev)1159 void bx_devices_c::unregister_removable_keyboard(void *dev)
1160 {
1161 if (dev == bx_keyboard[1].dev) {
1162 bx_keyboard[1].dev = NULL;
1163 bx_keyboard[1].gen_scancode = NULL;
1164 bx_keyboard[0].led_mask |= bx_keyboard[1].led_mask;
1165 bx_keyboard[1].led_mask = 0;
1166 }
1167 }
1168
register_default_mouse(void * dev,bx_mouse_enq_t mouse_enq,bx_mouse_enabled_changed_t mouse_enabled_changed)1169 void bx_devices_c::register_default_mouse(void *dev, bx_mouse_enq_t mouse_enq,
1170 bx_mouse_enabled_changed_t mouse_enabled_changed)
1171 {
1172 if (bx_mouse[0].dev == NULL) {
1173 bx_mouse[0].dev = dev;
1174 bx_mouse[0].enq_event = mouse_enq;
1175 bx_mouse[0].enabled_changed = mouse_enabled_changed;
1176 }
1177 }
1178
register_removable_mouse(void * dev,bx_mouse_enq_t mouse_enq,bx_mouse_enabled_changed_t mouse_enabled_changed)1179 void bx_devices_c::register_removable_mouse(void *dev, bx_mouse_enq_t mouse_enq,
1180 bx_mouse_enabled_changed_t mouse_enabled_changed)
1181 {
1182 if (bx_mouse[1].dev == NULL) {
1183 bx_mouse[1].dev = dev;
1184 bx_mouse[1].enq_event = mouse_enq;
1185 bx_mouse[1].enabled_changed = mouse_enabled_changed;
1186 }
1187 }
1188
unregister_removable_mouse(void * dev)1189 void bx_devices_c::unregister_removable_mouse(void *dev)
1190 {
1191 if (dev == bx_mouse[1].dev) {
1192 bx_mouse[1].dev = NULL;
1193 bx_mouse[1].enq_event = NULL;
1194 bx_mouse[1].enabled_changed = NULL;
1195 }
1196 }
1197
1198 // common keyboard device handlers
gen_scancode(Bit32u key)1199 void bx_devices_c::gen_scancode(Bit32u key)
1200 {
1201 bool ret = 0;
1202
1203 bx_keyboard[0].bxkey_state[key & 0xff] = ((key & BX_KEY_RELEASED) == 0);
1204 if ((paste.buf != NULL) && (!paste.service)) {
1205 paste.stop = 1;
1206 return;
1207 }
1208 if (bx_keyboard[1].dev != NULL) {
1209 ret = bx_keyboard[1].gen_scancode(bx_keyboard[1].dev, key);
1210 }
1211 if ((ret == 0) && (bx_keyboard[0].dev != NULL)) {
1212 bx_keyboard[0].gen_scancode(bx_keyboard[0].dev, key);
1213 }
1214 }
1215
kbd_get_elements(void)1216 Bit8u bx_devices_c::kbd_get_elements(void)
1217 {
1218 if (bx_keyboard[1].dev != NULL) {
1219 return bx_keyboard[1].get_elements(bx_keyboard[1].dev);
1220 }
1221 if (bx_keyboard[0].dev != NULL) {
1222 return bx_keyboard[0].get_elements(bx_keyboard[0].dev);
1223 }
1224 return BX_KBD_ELEMENTS;
1225 }
1226
release_keys()1227 void bx_devices_c::release_keys()
1228 {
1229 for (int i = 0; i < BX_KEY_NBKEYS; i++) {
1230 if (bx_keyboard[0].bxkey_state[i]) {
1231 gen_scancode(i | BX_KEY_RELEASED);
1232 bx_keyboard[0].bxkey_state[i] = 0;
1233 }
1234 }
1235 }
1236
1237 // service_paste_buf() transfers data from the paste buffer to the hardware
1238 // keyboard buffer. It tries to transfer as many chars as possible at a
1239 // time, but because different chars require different numbers of scancodes
1240 // we have to be conservative. Note that this process depends on the
1241 // keymap tables to know what chars correspond to what keys, and which
1242 // chars require a shift or other modifier.
service_paste_buf()1243 void bx_devices_c::service_paste_buf()
1244 {
1245 if (!paste.buf) return;
1246 BX_DEBUG(("service_paste_buf: ptr at %d out of %d", paste.buf_ptr, paste.buf_len));
1247 int fill_threshold = 8;
1248 paste.service = 1;
1249 while ((paste.buf_ptr < paste.buf_len) && !paste.stop) {
1250 if (kbd_get_elements() >= fill_threshold) {
1251 paste.service = 0;
1252 return;
1253 }
1254 // there room in the buffer for a keypress and a key release.
1255 // send one keypress and a key release.
1256 Bit8u byte = paste.buf[paste.buf_ptr];
1257 BXKeyEntry *entry = bx_keymap.findAsciiChar(byte);
1258 if (!entry) {
1259 BX_ERROR(("paste character 0x%02x ignored", byte));
1260 } else {
1261 BX_DEBUG(("pasting character 0x%02x. baseKey is %04x", byte, entry->baseKey));
1262 if (entry->modKey != BX_KEYMAP_UNKNOWN)
1263 gen_scancode(entry->modKey);
1264 gen_scancode(entry->baseKey);
1265 gen_scancode(entry->baseKey | BX_KEY_RELEASED);
1266 if (entry->modKey != BX_KEYMAP_UNKNOWN)
1267 gen_scancode(entry->modKey | BX_KEY_RELEASED);
1268 }
1269 paste.buf_ptr++;
1270 }
1271 // reached end of pastebuf. free the memory it was using.
1272 delete [] paste.buf;
1273 paste.buf = NULL;
1274 paste.stop = 0;
1275 paste.service = 0;
1276 }
1277
1278 // paste_bytes schedules an arbitrary number of ASCII characters to be
1279 // inserted into the hardware queue as it become available. Any previous
1280 // paste which is still in progress will be thrown out. BYTES is a pointer
1281 // to a region of memory containing the chars to be pasted. When the paste
1282 // is complete, the keyboard code will call delete [] bytes;
paste_bytes(Bit8u * data,Bit32s length)1283 void bx_devices_c::paste_bytes(Bit8u *data, Bit32s length)
1284 {
1285 BX_DEBUG(("paste_bytes: %d bytes", length));
1286 if (paste.buf) {
1287 BX_ERROR(("previous paste was not completed! %d chars lost",
1288 paste.buf_len - paste.buf_ptr));
1289 delete [] paste.buf; // free the old paste buffer
1290 }
1291 paste.buf = data;
1292 paste.buf_ptr = 0;
1293 paste.buf_len = length;
1294 service_paste_buf();
1295 }
1296
param_handler(bx_param_c * param,bool set,Bit64s val)1297 Bit64s bx_devices_c::param_handler(bx_param_c *param, bool set, Bit64s val)
1298 {
1299 if (set) {
1300 char pname[BX_PATHNAME_LEN];
1301 param->get_param_path(pname, BX_PATHNAME_LEN);
1302 if (set) {
1303 if (!strcmp(pname, BXPN_KBD_PASTE_DELAY)) {
1304 bx_devices.paste_delay_changed((Bit32u)val);
1305 } else if (!strcmp(pname, BXPN_MOUSE_ENABLED)) {
1306 bx_gui->mouse_enabled_changed(val!=0);
1307 bx_devices.mouse_enabled_changed(val!=0);
1308 } else {
1309 BX_PANIC(("param_handler called with unexpected parameter '%s'", pname));
1310 }
1311 }
1312 }
1313 return val;
1314 }
1315
paste_delay_changed(Bit32u value)1316 void bx_devices_c::paste_delay_changed(Bit32u value)
1317 {
1318 paste.delay = value / BX_IODEV_HANDLER_PERIOD;
1319 paste.counter = 0;
1320 BX_INFO(("will paste characters every %d iodev timer ticks", paste.delay));
1321 }
1322
kbd_set_indicator(Bit8u devid,Bit8u ledid,bool state)1323 void bx_devices_c::kbd_set_indicator(Bit8u devid, Bit8u ledid, bool state)
1324 {
1325 if (bx_keyboard[devid].led_mask & (1 << ledid)) {
1326 bx_gui->statusbar_setitem(statusbar_id[ledid], state, devid);
1327 }
1328 }
1329
1330 // common mouse device handlers
mouse_enabled_changed(bool enabled)1331 void bx_devices_c::mouse_enabled_changed(bool enabled)
1332 {
1333 mouse_captured = enabled;
1334
1335 if ((bx_mouse[1].dev != NULL) && (bx_mouse[1].enabled_changed != NULL)) {
1336 bx_mouse[1].enabled_changed(bx_mouse[1].dev, enabled);
1337 return;
1338 }
1339
1340 if ((bx_mouse[0].dev != NULL) && (bx_mouse[0].enabled_changed != NULL)) {
1341 bx_mouse[0].enabled_changed(bx_mouse[0].dev, enabled);
1342 }
1343 }
1344
mouse_motion(int delta_x,int delta_y,int delta_z,unsigned button_state,bool absxy)1345 void bx_devices_c::mouse_motion(int delta_x, int delta_y, int delta_z, unsigned button_state, bool absxy)
1346 {
1347 // If mouse events are disabled on the GUI headerbar, don't
1348 // generate any mouse data
1349 if (!mouse_captured)
1350 return;
1351
1352 // if a removable mouse is connected, redirect mouse data to the device
1353 if (bx_mouse[1].dev != NULL) {
1354 bx_mouse[1].enq_event(bx_mouse[1].dev, delta_x, delta_y, delta_z, button_state, absxy);
1355 return;
1356 }
1357
1358 // if a mouse is connected, direct mouse data to the device
1359 if (bx_mouse[0].dev != NULL) {
1360 bx_mouse[0].enq_event(bx_mouse[0].dev, delta_x, delta_y, delta_z, button_state, absxy);
1361 }
1362 }
1363
1364 #if BX_SUPPORT_PCI
1365 // generic PCI support
register_pci_handlers(bx_pci_device_c * dev,Bit8u * devfunc,const char * name,const char * descr,Bit8u bus)1366 bool bx_devices_c::register_pci_handlers(bx_pci_device_c *dev,
1367 Bit8u *devfunc, const char *name,
1368 const char *descr, Bit8u bus)
1369 {
1370 unsigned i, handle, max_pci_slots = BX_N_PCI_SLOTS;
1371 int first_free_slot = -1;
1372 Bit16u bus_devfunc = *devfunc;
1373 char devname[80];
1374 const char *device;
1375
1376 if (strcmp(name, "pci") && strcmp(name, "pci2isa") && strcmp(name, "pci_ide")
1377 && ((*devfunc & 0xf8) == 0x00)) {
1378 if ((SIM->get_param_enum(BXPN_PCI_CHIPSET)->get() == BX_PCI_CHIPSET_I440BX) &&
1379 (is_agp_present())) {
1380 max_pci_slots = 4;
1381 }
1382 if (bus == 0) {
1383 for (i = 0; i < max_pci_slots; i++) {
1384 sprintf(devname, "pci.slot.%d", i+1);
1385 device = SIM->get_param_enum(devname)->get_selected();
1386 if (strcmp(device, "none")) {
1387 if (!strcmp(name, device) && !pci.slot_used[i]) {
1388 *devfunc = ((i + pci.map_slot_to_dev) << 3) | (*devfunc & 0x07);
1389 pci.slot_used[i] = 1;
1390 BX_INFO(("PCI slot #%d used by plugin '%s'", i+1, name));
1391 break;
1392 }
1393 } else if (first_free_slot == -1) {
1394 first_free_slot = i;
1395 }
1396 }
1397 if ((*devfunc & 0xf8) == 0x00) {
1398 // auto-assign device to PCI slot if possible
1399 if (first_free_slot != -1) {
1400 i = (unsigned)first_free_slot;
1401 sprintf(devname, "pci.slot.%d", i+1);
1402 SIM->get_param_enum(devname)->set_by_name(name);
1403 *devfunc = ((i + pci.map_slot_to_dev) << 3) | (*devfunc & 0x07);
1404 pci.slot_used[i] = 1;
1405 BX_INFO(("PCI slot #%d used by plugin '%s'", i+1, name));
1406 } else {
1407 BX_ERROR(("Plugin '%s' not connected to a PCI slot", name));
1408 return 0;
1409 }
1410 }
1411 bus_devfunc = *devfunc;
1412 } else if ((bus == 1) && (max_pci_slots == 4)) {
1413 pci.slot_used[4] = 1;
1414 bus_devfunc = 0x100;
1415 } else {
1416 BX_PANIC(("Invalid bus number #%d", bus));
1417 return 0;
1418 }
1419 }
1420 /* check if device/function is available */
1421 if (pci.handler_id[bus_devfunc] == BX_MAX_PCI_DEVICES) {
1422 if (pci.num_pci_handlers >= BX_MAX_PCI_DEVICES) {
1423 BX_INFO(("too many PCI devices installed."));
1424 BX_PANIC((" try increasing BX_MAX_PCI_DEVICES"));
1425 return 0;
1426 }
1427 handle = pci.num_pci_handlers++;
1428 pci.pci_handler[handle].handler = dev;
1429 pci.handler_id[bus_devfunc] = handle;
1430 if (bus_devfunc < 0x100) {
1431 BX_INFO(("%s present at device %d, function %d", descr, *devfunc >> 3,
1432 *devfunc & 0x07));
1433 } else {
1434 BX_INFO(("%s present on AGP bus device #0", descr));
1435 }
1436 dev->set_name(descr);
1437 return 1; // device/function mapped successfully
1438 } else {
1439 return 0; // device/function not available, return false.
1440 }
1441 }
1442
pci_set_base_mem(void * this_ptr,memory_handler_t f1,memory_handler_t f2,Bit32u * addr,Bit8u * pci_conf,unsigned size)1443 bool bx_devices_c::pci_set_base_mem(void *this_ptr, memory_handler_t f1, memory_handler_t f2,
1444 Bit32u *addr, Bit8u *pci_conf, unsigned size)
1445 {
1446 Bit32u oldbase = *addr, newbase;
1447 Bit32u mask = ~(size - 1);
1448 Bit8u pci_flags = pci_conf[0x00] & 0x0f;
1449 if ((pci_flags & 0x06) > 0) {
1450 BX_ERROR(("Ignoring PCI base memory flag 0x%02x for now", pci_flags));
1451 }
1452 pci_conf[0x00] &= (mask & 0xf0);
1453 pci_conf[0x01] &= (mask >> 8) & 0xff;
1454 pci_conf[0x02] &= (mask >> 16) & 0xff;
1455 pci_conf[0x03] &= (mask >> 24) & 0xff;
1456 newbase = ReadHostDWordFromLittleEndian((Bit32u*)pci_conf);
1457 pci_conf[0x00] |= pci_flags;
1458 if (newbase != mask && newbase != oldbase) { // skip PCI probe
1459 if (oldbase > 0) {
1460 DEV_unregister_memory_handlers(this_ptr, oldbase, oldbase + size - 1);
1461 }
1462 if (newbase > 0) {
1463 DEV_register_memory_handlers(this_ptr, f1, f2, newbase, newbase + size - 1);
1464 }
1465 *addr = newbase;
1466 return 1;
1467 }
1468 return 0;
1469 }
1470
pci_set_base_io(void * this_ptr,bx_read_handler_t f1,bx_write_handler_t f2,Bit32u * addr,Bit8u * pci_conf,unsigned size,const Bit8u * iomask,const char * name)1471 bool bx_devices_c::pci_set_base_io(void *this_ptr, bx_read_handler_t f1, bx_write_handler_t f2,
1472 Bit32u *addr, Bit8u *pci_conf, unsigned size,
1473 const Bit8u *iomask, const char *name)
1474 {
1475 unsigned i;
1476 Bit32u oldbase = *addr, newbase;
1477 Bit16u mask = ~(size - 1);
1478 Bit8u pci_flags = pci_conf[0x00] & 0x03;
1479 pci_conf[0x00] &= (mask & 0xfc);
1480 pci_conf[0x01] &= (mask >> 8);
1481 newbase = ReadHostDWordFromLittleEndian((Bit32u*)pci_conf);
1482 pci_conf[0x00] |= pci_flags;
1483 if (((newbase & 0xfffc) != mask) && (newbase != oldbase)) { // skip PCI probe
1484 if (oldbase > 0) {
1485 for (i=0; i<size; i++) {
1486 if (iomask[i] > 0) {
1487 DEV_unregister_ioread_handler(this_ptr, f1, oldbase + i, iomask[i]);
1488 DEV_unregister_iowrite_handler(this_ptr, f2, oldbase + i, iomask[i]);
1489 }
1490 }
1491 }
1492 if (newbase > 0) {
1493 for (i=0; i<size; i++) {
1494 if (iomask[i] > 0) {
1495 DEV_register_ioread_handler(this_ptr, f1, newbase + i, name, iomask[i]);
1496 DEV_register_iowrite_handler(this_ptr, f2, newbase + i, name, iomask[i]);
1497 }
1498 }
1499 }
1500 *addr = newbase;
1501 return 1;
1502 }
1503 return 0;
1504 }
1505
1506 // PCI device base class (common methods)
1507 #undef LOG_THIS
1508 #define LOG_THIS
1509
init_pci_conf(Bit16u vid,Bit16u did,Bit8u rev,Bit32u classc,Bit8u headt,Bit8u intpin)1510 void bx_pci_device_c::init_pci_conf(Bit16u vid, Bit16u did, Bit8u rev,
1511 Bit32u classc, Bit8u headt, Bit8u intpin)
1512 {
1513 memset(pci_conf, 0, 256);
1514 pci_conf[0x00] = (Bit8u)(vid & 0xff);
1515 pci_conf[0x01] = (Bit8u)(vid >> 8);
1516 pci_conf[0x02] = (Bit8u)(did & 0xff);
1517 pci_conf[0x03] = (Bit8u)(did >> 8);
1518 pci_conf[0x08] = rev;
1519 pci_conf[0x09] = (Bit8u)(classc & 0xff);
1520 pci_conf[0x0a] = (Bit8u)((classc >> 8) & 0xff);
1521 pci_conf[0x0b] = (Bit8u)((classc >> 16) & 0xff);
1522 pci_conf[0x0e] = headt;
1523 pci_conf[0x3d] = intpin;
1524 }
1525
init_bar_io(Bit8u num,Bit16u size,bx_read_handler_t rh,bx_write_handler_t wh,const Bit8u * mask)1526 void bx_pci_device_c::init_bar_io(Bit8u num, Bit16u size, bx_read_handler_t rh,
1527 bx_write_handler_t wh, const Bit8u *mask)
1528 {
1529 if (num < 6) {
1530 pci_bar[num].type = BX_PCI_BAR_TYPE_IO;
1531 pci_bar[num].size = size;
1532 pci_bar[num].io.rh = rh;
1533 pci_bar[num].io.wh = wh;
1534 pci_bar[num].io.mask = mask;
1535 pci_conf[0x10 + num * 4] = 0x01;
1536 }
1537 }
1538
init_bar_mem(Bit8u num,Bit32u size,memory_handler_t rh,memory_handler_t wh)1539 void bx_pci_device_c::init_bar_mem(Bit8u num, Bit32u size, memory_handler_t rh,
1540 memory_handler_t wh)
1541 {
1542 if (num < 6) {
1543 pci_bar[num].type = BX_PCI_BAR_TYPE_MEM;
1544 pci_bar[num].size = size;
1545 pci_bar[num].mem.rh = rh;
1546 pci_bar[num].mem.wh = wh;
1547 }
1548 }
1549
register_pci_state(bx_list_c * list)1550 void bx_pci_device_c::register_pci_state(bx_list_c *list)
1551 {
1552 new bx_shadow_data_c(list, "pci_conf", pci_conf, 256, 1);
1553 }
1554
after_restore_pci_state(memory_handler_t mem_read_handler)1555 void bx_pci_device_c::after_restore_pci_state(memory_handler_t mem_read_handler)
1556 {
1557 for (int i = 0; i < 6; i++) {
1558 if (pci_bar[i].type == BX_PCI_BAR_TYPE_MEM) {
1559 if (DEV_pci_set_base_mem(this, pci_bar[i].mem.rh, pci_bar[i].mem.wh,
1560 &pci_bar[i].addr, &pci_conf[0x10 + i * 4],
1561 pci_bar[i].size)) {
1562 BX_INFO(("BAR #%d: mem base address = 0x%08x", i, pci_bar[i].addr));
1563 pci_bar_change_notify();
1564 }
1565 } else if (pci_bar[i].type == BX_PCI_BAR_TYPE_IO) {
1566 if (DEV_pci_set_base_io(this, pci_bar[i].io.rh, pci_bar[i].io.wh,
1567 &pci_bar[i].addr, &pci_conf[0x10 + i * 4],
1568 pci_bar[i].size, pci_bar[i].io.mask, pci_name)) {
1569 BX_INFO(("BAR #%d: i/o base address = 0x%04x", i, pci_bar[i].addr));
1570 pci_bar_change_notify();
1571 }
1572 }
1573 }
1574 if (pci_rom_size > 0) {
1575 if (DEV_pci_set_base_mem(this, mem_read_handler, NULL, &pci_rom_address,
1576 &pci_conf[0x30], pci_rom_size)) {
1577 BX_INFO(("new ROM address: 0x%08x", pci_rom_address));
1578 }
1579 }
1580 }
1581
load_pci_rom(const char * path)1582 void bx_pci_device_c::load_pci_rom(const char *path)
1583 {
1584 struct stat stat_buf;
1585 int fd, ret;
1586 unsigned long size, max_size;
1587
1588 if (*path == '\0') {
1589 BX_PANIC(("PCI ROM image undefined"));
1590 return;
1591 }
1592 // read in PCI ROM image file
1593 fd = open(path, O_RDONLY
1594 #ifdef O_BINARY
1595 | O_BINARY
1596 #endif
1597 );
1598 if (fd < 0) {
1599 BX_PANIC(("couldn't open PCI ROM image file '%s'.", path));
1600 return;
1601 }
1602 ret = fstat(fd, &stat_buf);
1603 if (ret) {
1604 close(fd);
1605 BX_PANIC(("couldn't stat PCI ROM image file '%s'.", path));
1606 return;
1607 }
1608
1609 max_size = 0x20000;
1610 size = (unsigned long)stat_buf.st_size;
1611 if (size > max_size) {
1612 close(fd);
1613 BX_PANIC(("PCI ROM image too large"));
1614 return;
1615 }
1616 if ((size % 512) != 0) {
1617 close(fd);
1618 BX_PANIC(("PCI ROM image size must be multiple of 512 (size = %ld)", size));
1619 return;
1620 }
1621 while ((size - 1) < max_size) {
1622 max_size >>= 1;
1623 }
1624 pci_rom_size = (max_size << 1);
1625 pci_rom = new Bit8u[pci_rom_size];
1626
1627 while (size > 0) {
1628 ret = read(fd, (bx_ptr_t) pci_rom, size);
1629 if (ret <= 0) {
1630 BX_PANIC(("read failed on PCI ROM image: '%s'", path));
1631 }
1632 size -= ret;
1633 }
1634 close(fd);
1635
1636 BX_INFO(("loaded PCI ROM '%s' (size=%u / PCI=%uk)", path, (unsigned) stat_buf.st_size, pci_rom_size >> 10));
1637 }
1638
1639 // pci configuration space write callback handler (common registers)
pci_write_handler_common(Bit8u address,Bit32u value,unsigned io_len)1640 void bx_pci_device_c::pci_write_handler_common(Bit8u address, Bit32u value, unsigned io_len)
1641 {
1642 Bit8u bnum, value8, oldval;
1643 bool bar_change = 0, rom_change = 0;
1644
1645 // ignore readonly registers
1646 if ((address < 4) || ((address > 7) && (address < 12)) || (address == 14) ||
1647 (address == 0x3d)) {
1648 BX_DEBUG(("write to r/o PCI register 0x%02x ignored", address));
1649 return;
1650 }
1651
1652 // handle base address registers if header type bit #0 and #1 are clear
1653 if (((pci_conf[0x0e] & 0x03) == 0) && (address >= 0x10) && (address < 0x28)) {
1654 bnum = ((address - 0x10) >> 2);
1655 if (pci_bar[bnum].type != BX_PCI_BAR_TYPE_NONE) {
1656 BX_DEBUG_PCI_WRITE(address, value, io_len);
1657 for (unsigned i=0; i<io_len; i++) {
1658 value8 = (value >> (i*8)) & 0xff;
1659 oldval = pci_conf[address+i];
1660 if (((address+i) & 0x03) == 0) {
1661 if (pci_bar[bnum].type == BX_PCI_BAR_TYPE_IO) {
1662 value8 = (value8 & 0xfc) | 0x01;
1663 } else {
1664 value8 = (value8 & 0xf0) | (oldval & 0x0f);
1665 }
1666 }
1667 bar_change |= (value8 != oldval);
1668 pci_conf[address+i] = value8;
1669 }
1670 if (bar_change) {
1671 if (pci_bar[bnum].type == BX_PCI_BAR_TYPE_IO) {
1672 if (DEV_pci_set_base_io(this, pci_bar[bnum].io.rh, pci_bar[bnum].io.wh,
1673 &pci_bar[bnum].addr, &pci_conf[0x10 + bnum * 4],
1674 pci_bar[bnum].size, pci_bar[bnum].io.mask, pci_name)) {
1675 BX_INFO(("BAR #%d: i/o base address = 0x%04x", bnum, pci_bar[bnum].addr));
1676 pci_bar_change_notify();
1677 }
1678 } else {
1679 if (DEV_pci_set_base_mem(this, pci_bar[bnum].mem.rh, pci_bar[bnum].mem.wh,
1680 &pci_bar[bnum].addr, &pci_conf[0x10 + bnum * 4],
1681 pci_bar[bnum].size)) {
1682 BX_INFO(("BAR #%d: mem base address = 0x%08x", bnum, pci_bar[bnum].addr));
1683 pci_bar_change_notify();
1684 }
1685 }
1686 }
1687 }
1688 } else if ((address & 0xfc) == 0x30) {
1689 BX_DEBUG_PCI_WRITE(address, value, io_len);
1690 value &= (0xfffffc01 >> ((address & 0x03) * 8));
1691 for (unsigned i=0; i<io_len; i++) {
1692 value8 = (value >> (i*8)) & 0xff;
1693 oldval = pci_conf[address+i];
1694 rom_change |= (value8 != oldval);
1695 pci_conf[address+i] = value8;
1696 }
1697 if (rom_change) {
1698 if (DEV_pci_set_base_mem(this, pci_rom_read_handler, NULL,
1699 &pci_rom_address, &pci_conf[0x30],
1700 pci_rom_size)) {
1701 BX_INFO(("new ROM address = 0x%08x", pci_rom_address));
1702 }
1703 }
1704 } else if (address == 0x3c) {
1705 value8 = (Bit8u)value;
1706 if (value8 != pci_conf[0x3c]) {
1707 if (pci_conf[0x3d] != 0) {
1708 BX_INFO(("new IRQ line = %d", value8));
1709 }
1710 pci_conf[0x3c] = value8;
1711 }
1712 } else {
1713 pci_write_handler(address, value, io_len);
1714 }
1715 }
1716
1717 // pci configuration space read callback handler
pci_read_handler(Bit8u address,unsigned io_len)1718 Bit32u bx_pci_device_c::pci_read_handler(Bit8u address, unsigned io_len)
1719 {
1720 Bit32u value = 0;
1721
1722 for (unsigned i=0; i<io_len; i++) {
1723 value |= (pci_conf[address+i] << (i*8));
1724 }
1725
1726 BX_DEBUG_PCI_READ(address, value, io_len);
1727
1728 return value;
1729 }
1730 #endif
1731