OpenCores
URL https://opencores.org/ocsvn/zet86/zet86/trunk

Subversion Repositories zet86

[/] [zet86/] [trunk/] [src/] [bochs-diff-2.3.7/] [iodev/] [devices.cc] - Blame information for rev 49

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 39 zeus
/////////////////////////////////////////////////////////////////////////
2 43 zeus
// $Id: devices.cc,v 1.5 2009-02-06 03:48:32 zeus Exp $
3 39 zeus
/////////////////////////////////////////////////////////////////////////
4
//
5
//  Copyright (C) 2002  MandrakeSoft S.A.
6
//
7
//    MandrakeSoft S.A.
8
//    43, rue d'Aboukir
9
//    75002 Paris - France
10
//    http://www.linux-mandrake.com/
11
//    http://www.mandrakesoft.com/
12
//
13
//  I/O port handlers API Copyright (C) 2003 by Frank Cornelis
14
//
15
//  This library is free software; you can redistribute it and/or
16
//  modify it under the terms of the GNU Lesser General Public
17
//  License as published by the Free Software Foundation; either
18
//  version 2 of the License, or (at your option) any later version.
19
//
20
//  This library is distributed in the hope that it will be useful,
21
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
22
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23
//  Lesser General Public License for more details.
24
//
25
//  You should have received a copy of the GNU Lesser General Public
26
//  License along with this library; if not, write to the Free Software
27
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
28
//
29
/////////////////////////////////////////////////////////////////////////
30
 
31
 
32
#include "bochs.h"
33
#include "iodev.h"
34
#define LOG_THIS bx_devices.
35
 
36
 
37
/* main memory size (in Kbytes)
38
 * subtract 1k for extended BIOS area
39
 * report only base memory, not extended mem
40
 */
41
#define BASE_MEMORY_IN_K  640
42
 
43
 
44
bx_devices_c bx_devices;
45
 
46
 
47
// constructor for bx_devices_c
48
bx_devices_c::bx_devices_c()
49
{
50
  put("DEV");
51
  settype(DEVLOG);
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
}
65
 
66
bx_devices_c::~bx_devices_c()
67
{
68
  // nothing needed for now
69
  timer_handle = BX_NULL_TIMER_HANDLE;
70
}
71
 
72
void bx_devices_c::init_stubs()
73
{
74
#if BX_SUPPORT_PCI
75
  pluginPciBridge = &stubPci;
76
  pluginPci2IsaBridge = &stubPci2Isa;
77
  pluginPciIdeController = &stubPciIde;
78
#if BX_SUPPORT_ACPI
79
  pluginACPIController = &stubACPIController;
80
#endif
81
#if BX_SUPPORT_PCIVGA
82
    pluginPciVgaAdapter = NULL;
83
#endif
84
#if BX_SUPPORT_PCIDEV
85
    pluginPciDevAdapter = NULL;
86
#endif
87
#if BX_SUPPORT_PCIUSB
88
    pluginPciUSBAdapter = &stubUsbAdapter;
89
#endif
90
#if BX_SUPPORT_PCIPNIC
91
    pluginPciPNicAdapter = NULL;
92
#endif
93
#endif
94
  pit = NULL;
95
  pluginKeyboard = &stubKeyboard;
96
  pluginDmaDevice = &stubDma;
97
  pluginFloppyDevice = &stubFloppy;
98
  pluginBiosDevice = NULL;
99
  pluginCmosDevice = &stubCmos;
100
  pluginSerialDevice = &stubSerial;
101
  pluginParallelDevice = NULL;
102
  pluginUnmapped = NULL;
103
  pluginVgaDevice = &stubVga;
104
  pluginPicDevice = &stubPic;
105
  pluginHardDrive = &stubHardDrive;
106
  pluginSB16Device = NULL;
107
  pluginNE2kDevice =&stubNE2k;
108
  pluginExtFpuIrq = NULL;
109
  pluginGameport = NULL;
110
  pluginSpeaker = &stubSpeaker;
111
#if BX_SUPPORT_BUSMOUSE
112
  pluginBusMouse = &stubBusMouse;
113
#endif
114
#if BX_SUPPORT_IODEBUG
115
  iodebug = NULL;
116
#endif
117
#if 0
118
  g2h = NULL;
119
#endif
120
}
121
 
122
void bx_devices_c::init(BX_MEM_C *newmem)
123
{
124
  unsigned i;
125
  const char def_name[] = "Default";
126
 
127 43 zeus
  BX_DEBUG(("Init $Id: devices.cc,v 1.5 2009-02-06 03:48:32 zeus Exp $"));
128 39 zeus
  mem = newmem;
129
 
130
  /* set no-default handlers, will be overwritten by the real default handler */
131
  register_default_io_read_handler(NULL, &default_read_handler, def_name, 7);
132
  io_read_handlers.next = &io_read_handlers;
133
  io_read_handlers.prev = &io_read_handlers;
134
  io_read_handlers.usage_count = 0; // not used with the default handler
135
 
136
  register_default_io_write_handler(NULL, &default_write_handler, def_name, 7);
137
  io_write_handlers.next = &io_write_handlers;
138
  io_write_handlers.prev = &io_write_handlers;
139
  io_write_handlers.usage_count = 0; // not used with the default handler
140
 
141
  if (read_port_to_handler)
142
    delete [] read_port_to_handler;
143
  if (write_port_to_handler)
144
    delete [] write_port_to_handler;
145
  read_port_to_handler = new struct io_handler_struct *[PORTS];
146
  write_port_to_handler = new struct io_handler_struct *[PORTS];
147
 
148
  /* set handlers to the default one */
149
  for (i=0; i < PORTS; i++) {
150
    read_port_to_handler[i] = &io_read_handlers;
151
    write_port_to_handler[i] = &io_write_handlers;
152
  }
153
 
154
  for (i=0; i < BX_MAX_IRQS; i++) {
155
    delete [] irq_handler_name[i];
156
    irq_handler_name[i] = NULL;
157
  }
158
 
159
  // register as soon as possible - the devices want to have their timers !
160
  bx_virt_timer.init();
161
  bx_slowdown_timer.init();
162
 
163
  // BBD: At present, the only difference between "core" and "optional"
164
  // plugins is that initialization and reset of optional plugins is handled
165
  // by the plugin device list ().  Init and reset of core plugins is done
166
  // "by hand" in this file.  Basically, we're using core plugins when we
167
  // want to control the init order.
168
  //
169
  // CB: UNMAPPED and BIOSDEV should maybe be optional
170
  PLUG_load_plugin(unmapped, PLUGTYPE_CORE);
171
  PLUG_load_plugin(biosdev, PLUGTYPE_CORE);
172
  PLUG_load_plugin(cmos, PLUGTYPE_CORE);
173
/*
174
  PLUG_load_plugin(dma, PLUGTYPE_CORE);
175
  PLUG_load_plugin(pic, PLUGTYPE_CORE);
176
*/
177
  PLUG_load_plugin(vga, PLUGTYPE_CORE);
178
/*
179
  PLUG_load_plugin(floppy, PLUGTYPE_CORE);
180
  PLUG_load_plugin(harddrv, PLUGTYPE_OPTIONAL);
181
  PLUG_load_plugin(keyboard, PLUGTYPE_OPTIONAL);
182
#if BX_SUPPORT_BUSMOUSE
183
  if (SIM->get_param_enum(BXPN_MOUSE_TYPE)->get() == BX_MOUSE_TYPE_BUS) {
184
    PLUG_load_plugin(busmouse, PLUGTYPE_OPTIONAL);
185
  }
186
#endif
187
  if (is_serial_enabled())
188
    PLUG_load_plugin(serial, PLUGTYPE_OPTIONAL);
189
  if (is_parallel_enabled())
190
    PLUG_load_plugin(parallel, PLUGTYPE_OPTIONAL);
191
*/
192
  PLUG_load_plugin(hdemu, PLUGTYPE_OPTIONAL);
193
/*
194
  PLUG_load_plugin(extfpuirq, PLUGTYPE_OPTIONAL);
195
#if BX_SUPPORT_GAMEPORT
196
  PLUG_load_plugin(gameport, PLUGTYPE_OPTIONAL);
197
#endif
198
  PLUG_load_plugin(speaker, PLUGTYPE_OPTIONAL);
199
*/
200
  // Start with registering the default (unmapped) handler
201
  pluginUnmapped->init ();
202
/*
203
  // PCI logic (i440FX)
204
  if (SIM->get_param_bool(BXPN_I440FX_SUPPORT)->get()) {
205
#if BX_SUPPORT_PCI
206
    PLUG_load_plugin(pci, PLUGTYPE_CORE);
207
    PLUG_load_plugin(pci2isa, PLUGTYPE_CORE);
208
    PLUG_load_plugin(pci_ide, PLUGTYPE_OPTIONAL);
209
#if BX_SUPPORT_ACPI
210
    PLUG_load_plugin(acpi, PLUGTYPE_OPTIONAL);
211
#endif
212
#if BX_SUPPORT_PCIVGA
213
    if ((DEV_is_pci_device("pcivga")) &&
214
        (!strcmp(SIM->get_param_string(BXPN_VGA_EXTENSION)->getptr(), "vbe"))) {
215
      PLUG_load_plugin(pcivga, PLUGTYPE_OPTIONAL);
216
    }
217
#endif
218
#if BX_SUPPORT_PCIUSB
219
    if (is_usb_enabled()) {
220
      PLUG_load_plugin(pciusb, PLUGTYPE_OPTIONAL);
221
    }
222
#endif
223
#if BX_SUPPORT_PCIDEV
224
    if (SIM->get_param_num(BXPN_PCIDEV_VENDOR)->get() != 0xffff) {
225
      PLUG_load_plugin(pcidev, PLUGTYPE_OPTIONAL);
226
    }
227
#endif
228
#if BX_SUPPORT_PCIPNIC
229
  if (SIM->get_param_bool(BXPN_PNIC_ENABLED)->get()) {
230
    PLUG_load_plugin(pcipnic, PLUGTYPE_OPTIONAL);
231
  }
232
#endif
233
#else
234
    BX_ERROR(("Bochs is not compiled with PCI support"));
235
#endif
236
  }
237
 
238
  // NE2000 NIC
239
  if (SIM->get_param_bool(BXPN_NE2K_ENABLED)->get()) {
240
#if BX_SUPPORT_NE2K
241
    PLUG_load_plugin(ne2k, PLUGTYPE_OPTIONAL);
242
#else
243
    BX_ERROR(("Bochs is not compiled with NE2K support"));
244
#endif
245
  }
246
 
247
#if BX_SUPPORT_APIC
248
  // I/O APIC 82093AA
249
  ioapic = & bx_ioapic;
250
  ioapic->init ();
251
#endif
252
*/
253
  // BIOS log
254
  pluginBiosDevice->init ();
255
 
256
  // CMOS RAM & RTC
257
  pluginCmosDevice->init ();
258
/*
259
  //--- 8237 DMA ---
260
  pluginDmaDevice->init();
261
 
262
  //--- FLOPPY ---
263
  pluginFloppyDevice->init();
264
 
265
  //--- SOUND ---
266
  if (SIM->get_param_bool(BXPN_SB16_ENABLED)->get()) {
267
#if BX_SUPPORT_SB16
268
    PLUG_load_plugin(sb16, PLUGTYPE_OPTIONAL);
269
#else
270
    BX_ERROR(("Bochs is not compiled with SB16 support"));
271
#endif
272
  }
273
 
274
#if BX_SUPPORT_PCI
275
  pluginPciBridge->init ();
276
  pluginPci2IsaBridge->init ();
277
#endif
278
*/
279
  //--- VGA adapter ---
280
  pluginVgaDevice->init ();
281
/*
282
  //--- 8259A PIC ---
283
  pluginPicDevice->init();
284
 
285
  //--- 8254 PIT ---
286
  pit = & bx_pit;
287
  pit->init();
288
 
289
#if BX_SUPPORT_IODEBUG
290
  iodebug = &bx_iodebug;
291
  iodebug->init();
292
#endif
293
 
294
#if 0
295
  // Guest to Host interface.  Used with special guest drivers
296
  // which move data to/from the host environment.
297
  g2h = &bx_g2h;
298
  g2h->init();
299
#endif
300
*/
301
  // system hardware
302
  register_io_read_handler(this, &read_handler, 0x0092,
303
                           "Port 92h System Control", 1);
304
  register_io_write_handler(this, &write_handler, 0x0092,
305
                            "Port 92h System Control", 1);
306
 
307
  // misc. CMOS
308
  Bit32u extended_memory_in_k = mem->get_memory_in_k() > 1024 ? (mem->get_memory_in_k() - 1024) : 0;
309
  if (extended_memory_in_k > 0xfc00) extended_memory_in_k = 0xfc00;
310
 
311
  DEV_cmos_set_reg(0x15, (Bit8u) BASE_MEMORY_IN_K);
312
  DEV_cmos_set_reg(0x16, (Bit8u) (BASE_MEMORY_IN_K >> 8));
313
  DEV_cmos_set_reg(0x17, (Bit8u) (extended_memory_in_k & 0xff));
314
  DEV_cmos_set_reg(0x18, (Bit8u) ((extended_memory_in_k >> 8) & 0xff));
315
  DEV_cmos_set_reg(0x30, (Bit8u) (extended_memory_in_k & 0xff));
316
  DEV_cmos_set_reg(0x31, (Bit8u) ((extended_memory_in_k >> 8) & 0xff));
317
 
318
  Bit32u extended_memory_in_64k = mem->get_memory_in_k() > 16384 ? (mem->get_memory_in_k() - 16384) / 64 : 0;
319
  if (extended_memory_in_64k > 0xffff) extended_memory_in_64k = 0xffff;
320
 
321
  DEV_cmos_set_reg(0x34, (Bit8u) (extended_memory_in_64k & 0xff));
322
  DEV_cmos_set_reg(0x35, (Bit8u) ((extended_memory_in_64k >> 8) & 0xff));
323
/*
324
  if (timer_handle != BX_NULL_TIMER_HANDLE) {
325
    timer_handle = bx_pc_system.register_timer(this, timer_handler,
326
      (unsigned) BX_IODEV_HANDLER_PERIOD, 1, 1, "devices.cc");
327
  }
328
*/
329
  // Clear fields for bulk IO acceleration transfers.
330
  bulkIOHostAddr = 0;
331
  bulkIOQuantumsRequested = 0;
332
  bulkIOQuantumsTransferred = 0;
333
 
334
  bx_init_plugins();
335
 
336
  /* now perform checksum of CMOS memory */
337
  DEV_cmos_checksum();
338
}
339
 
340
void bx_devices_c::reset(unsigned type)
341
{
342
  mem->disable_smram();
343
  pluginUnmapped->reset(type);
344
#if BX_SUPPORT_PCI
345
  if (SIM->get_param_bool(BXPN_I440FX_SUPPORT)->get()) {
346
    pluginPciBridge->reset(type);
347
    pluginPci2IsaBridge->reset(type);
348
  }
349
#endif
350
#if BX_SUPPORT_APIC
351
  ioapic->reset(type);
352
#endif
353
  pluginBiosDevice->reset(type);
354
  pluginCmosDevice->reset(type);
355
  pluginDmaDevice->reset(type);
356
  pluginFloppyDevice->reset(type);
357
  pluginVgaDevice->reset(type);
358
  pluginPicDevice->reset(type);
359
  pit->reset(type);
360
#if BX_SUPPORT_IODEBUG
361
  iodebug->reset(type);
362
#endif
363
  // now reset optional plugins
364
  bx_reset_plugins(type);
365
}
366
 
367
void bx_devices_c::register_state()
368
{
369
  bx_virt_timer.register_state();
370
#if BX_SUPPORT_PCI
371
  if (SIM->get_param_bool(BXPN_I440FX_SUPPORT)->get()) {
372
    pluginPciBridge->register_state();
373
    pluginPci2IsaBridge->register_state();
374
  }
375
#endif
376
#if BX_SUPPORT_APIC
377
  ioapic->register_state();
378
#endif
379
  pluginCmosDevice->register_state();
380
  pluginDmaDevice->register_state();
381
  pluginFloppyDevice->register_state();
382
  pluginVgaDevice->register_state();
383
  pluginPicDevice->register_state();
384
  pit->register_state();
385
  // now register state of optional plugins
386
  bx_plugins_register_state();
387
}
388
 
389
void bx_devices_c::after_restore_state()
390
{
391
  bx_slowdown_timer.after_restore_state();
392
#if BX_SUPPORT_PCI
393
  if (SIM->get_param_bool(BXPN_I440FX_SUPPORT)->get()) {
394
    pluginPciBridge->after_restore_state();
395
    pluginPci2IsaBridge->after_restore_state();
396
  }
397
#endif
398
  pluginCmosDevice->after_restore_state();
399
  pluginVgaDevice->after_restore_state();
400
  bx_plugins_after_restore_state();
401
}
402
 
403
void bx_devices_c::exit()
404
{
405
  // delete i/o handlers before unloading plugins
406
  struct io_handler_struct *io_read_handler = io_read_handlers.next;
407
  struct io_handler_struct *curr = NULL;
408
  while (io_read_handler != &io_read_handlers) {
409
    io_read_handler->prev->next = io_read_handler->next;
410
    io_read_handler->next->prev = io_read_handler->prev;
411
    curr = io_read_handler;
412
    io_read_handler = io_read_handler->next;
413
    delete [] curr->handler_name;
414
    delete curr;
415
  }
416
  struct io_handler_struct *io_write_handler = io_write_handlers.next;
417
  while (io_write_handler != &io_write_handlers) {
418
    io_write_handler->prev->next = io_write_handler->next;
419
    io_write_handler->next->prev = io_write_handler->prev;
420
    curr = io_write_handler;
421
    io_write_handler = io_write_handler->next;
422
    delete [] curr->handler_name;
423
    delete curr;
424
  }
425
 
426
  pit->exit();
427
  bx_virt_timer.setup();
428
  bx_slowdown_timer.exit();
429
 
430
  PLUG_unload_plugin(unmapped);
431
  PLUG_unload_plugin(biosdev);
432
  PLUG_unload_plugin(cmos);
433
  PLUG_unload_plugin(dma);
434
  PLUG_unload_plugin(pic);
435
  PLUG_unload_plugin(vga);
436
  PLUG_unload_plugin(floppy);
437
#if BX_SUPPORT_PCI
438
  PLUG_unload_plugin(pci);
439
  PLUG_unload_plugin(pci2isa);
440
#endif
441
  bx_unload_plugins();
442
  init_stubs();
443
}
444
 
445
Bit32u bx_devices_c::read_handler(void *this_ptr, Bit32u address, unsigned io_len)
446
{
447
#if !BX_USE_DEV_SMF
448
  bx_devices_c *class_ptr = (bx_devices_c *) this_ptr;
449
  return class_ptr->port92_read(address, io_len);
450
}
451
 
452
Bit32u bx_devices_c::port92_read(Bit32u address, unsigned io_len)
453
{
454
#else
455
  UNUSED(this_ptr);
456
#endif  // !BX_USE_DEV_SMF
457
 
458
  BX_DEBUG(("port92h read partially supported!!!"));
459
  BX_DEBUG(("  returning %02x", (unsigned) (BX_GET_ENABLE_A20() << 1)));
460
  return(BX_GET_ENABLE_A20() << 1);
461
}
462
 
463
void bx_devices_c::write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len)
464
{
465
#if !BX_USE_DEV_SMF
466
  bx_devices_c *class_ptr = (bx_devices_c *) this_ptr;
467
  class_ptr->port92_write(address, value, io_len);
468
}
469
 
470
void bx_devices_c::port92_write(Bit32u address, Bit32u value, unsigned io_len)
471
{
472
#else
473
  UNUSED(this_ptr);
474
#endif  // !BX_USE_DEV_SMF
475
 
476
  BX_DEBUG(("port92h write of %02x partially supported!!!", (unsigned) value));
477
  BX_DEBUG(("A20: set_enable_a20() called"));
478
  BX_SET_ENABLE_A20((value & 0x02) >> 1);
479
  BX_DEBUG(("A20: now %u", (unsigned) BX_GET_ENABLE_A20()));
480
  if (value & 0x01) { /* high speed reset */
481
    BX_INFO(("iowrite to port0x92 : reset resquested"));
482
    bx_pc_system.Reset(BX_RESET_SOFTWARE);
483
  }
484
}
485
 
486
// This defines a no-default read handler,
487
// so Bochs does not segfault if unmapped is not loaded
488
Bit32u bx_devices_c::default_read_handler(void *this_ptr, Bit32u address, unsigned io_len)
489
{
490
  UNUSED(this_ptr);
491
  BX_PANIC(("No default io-read handler found for 0x%04x/%d. Unmapped io-device not loaded ?", address, io_len));
492
  return 0xffffffff;
493
}
494
 
495
// This defines a no-default write handler,
496
// so Bochs does not segfault if unmapped is not loaded
497
void bx_devices_c::default_write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len)
498
{
499
  UNUSED(this_ptr);
500
  BX_PANIC(("No default io-write handler found for 0x%04x/%d. Unmapped io-device not loaded ?", address, io_len));
501
}
502
 
503
void bx_devices_c::timer_handler(void *this_ptr)
504
{
505
  bx_devices_c *class_ptr = (bx_devices_c *) this_ptr;
506
  class_ptr->timer();
507
}
508
 
509
void bx_devices_c::timer()
510
{
511
  // separate calls to bx_gui->handle_events from the keyboard code.
512
  {
513
    static int multiple=0;
514
    if (++multiple==10)
515
    {
516
      multiple=0;
517
      SIM->periodic();
518
      if (! bx_pc_system.kill_bochs_request)
519
        bx_gui->handle_events();
520
    }
521
  }
522
}
523
 
524
bx_bool bx_devices_c::register_irq(unsigned irq, const char *name)
525
{
526
  if (irq >= BX_MAX_IRQS) {
527
    BX_PANIC(("IO device %s registered with IRQ=%d above %u",
528
             name, irq, (unsigned) BX_MAX_IRQS-1));
529
    return 0;
530
  }
531
  if (irq_handler_name[irq]) {
532
    BX_PANIC(("IRQ %u conflict, %s with %s", irq,
533
      irq_handler_name[irq], name));
534
    return 0;
535
  }
536
  irq_handler_name[irq] = new char[strlen(name)+1];
537
  strcpy(irq_handler_name[irq], name);
538
  return 1;
539
}
540
 
541
bx_bool bx_devices_c::unregister_irq(unsigned irq, const char *name)
542
{
543
  if (irq >= BX_MAX_IRQS) {
544
    BX_PANIC(("IO device %s tried to unregister IRQ %d above %u",
545
             name, irq, (unsigned) BX_MAX_IRQS-1));
546
    return 0;
547
  }
548
  if (!irq_handler_name[irq]) {
549
    BX_INFO(("IO device %s tried to unregister IRQ %d, not registered",
550
              name, irq));
551
    return 0;
552
  }
553
 
554
  if (strcmp(irq_handler_name[irq], name)) {
555
    BX_INFO(("IRQ %u not registered to %s but to %s", irq,
556
      name, irq_handler_name[irq]));
557
    return 0;
558
  }
559
  delete [] irq_handler_name[irq];
560
  irq_handler_name[irq] = NULL;
561
  return 1;
562
}
563
 
564
bx_bool bx_devices_c::register_io_read_handler(void *this_ptr, bx_read_handler_t f,
565
                                               Bit32u addr, const char *name, Bit8u mask)
566
{
567
  addr &= 0x0000ffff;
568
 
569
  if (!f)
570
    return 0;
571
 
572
  /* first check if the port already has a handlers != the default handler */
573
  if (read_port_to_handler[addr] &&
574
      read_port_to_handler[addr] != &io_read_handlers) { // the default
575
    BX_ERROR(("IO device address conflict(read) at IO address %Xh",
576
              (unsigned) addr));
577
    BX_ERROR(("  conflicting devices: %s & %s",
578
              read_port_to_handler[addr]->handler_name, name));
579
    return 0;
580
  }
581
 
582
  /* first find existing handle for function or create new one */
583
  struct io_handler_struct *curr = &io_read_handlers;
584
  struct io_handler_struct *io_read_handler = NULL;
585
  do {
586
    if (curr->funct == f &&
587
        curr->mask == mask &&
588
        curr->this_ptr == this_ptr &&
589
        curr->handler_name == name) { // really want the same name too
590
      io_read_handler = curr;
591
      break;
592
    }
593
    curr = curr->next;
594
  } while (curr->next != &io_read_handlers);
595
 
596
  if (!io_read_handler) {
597
    io_read_handler = new struct io_handler_struct;
598
    io_read_handler->funct = (void *)f;
599
    io_read_handler->this_ptr = this_ptr;
600
    io_read_handler->handler_name = new char[strlen(name)+1];
601
    strcpy(io_read_handler->handler_name, name);
602
    io_read_handler->mask = mask;
603
    io_read_handler->usage_count = 0;
604
    // add the handler to the double linked list of handlers
605
    io_read_handlers.prev->next = io_read_handler;
606
    io_read_handler->next = &io_read_handlers;
607
    io_read_handler->prev = io_read_handlers.prev;
608
    io_read_handlers.prev = io_read_handler;
609
  }
610
 
611
  io_read_handler->usage_count++;
612
  read_port_to_handler[addr] = io_read_handler;
613
  return 1; // address mapped successfully
614
}
615
 
616
bx_bool bx_devices_c::register_io_write_handler(void *this_ptr, bx_write_handler_t f,
617
                                                Bit32u addr, const char *name, Bit8u mask)
618
{
619
  addr &= 0x0000ffff;
620
 
621
  if (!f)
622
    return 0;
623
 
624
  /* first check if the port already has a handlers != the default handler */
625
  if (write_port_to_handler[addr] &&
626
      write_port_to_handler[addr] != &io_write_handlers) { // the default
627
    BX_ERROR(("IO device address conflict(write) at IO address %Xh",
628
              (unsigned) addr));
629
    BX_ERROR(("  conflicting devices: %s & %s",
630
              write_port_to_handler[addr]->handler_name, name));
631
    return 0;
632
  }
633
 
634
  /* first find existing handle for function or create new one */
635
  struct io_handler_struct *curr = &io_write_handlers;
636
  struct io_handler_struct *io_write_handler = NULL;
637
  do {
638
    if (curr->funct == f &&
639
        curr->mask == mask &&
640
        curr->this_ptr == this_ptr &&
641
        curr->handler_name == name) { // really want the same name too
642
      io_write_handler = curr;
643
      break;
644
    }
645
    curr = curr->next;
646
  } while (curr->next != &io_write_handlers);
647
 
648
  if (!io_write_handler) {
649
    io_write_handler = new struct io_handler_struct;
650
    io_write_handler->funct = (void *)f;
651
    io_write_handler->this_ptr = this_ptr;
652
    io_write_handler->handler_name = new char[strlen(name)+1];
653
    strcpy(io_write_handler->handler_name, name);
654
    io_write_handler->mask = mask;
655
    io_write_handler->usage_count = 0;
656
    // add the handler to the double linked list of handlers
657
    io_write_handlers.prev->next = io_write_handler;
658
    io_write_handler->next = &io_write_handlers;
659
    io_write_handler->prev = io_write_handlers.prev;
660
    io_write_handlers.prev = io_write_handler;
661
  }
662
 
663
  io_write_handler->usage_count++;
664
  write_port_to_handler[addr] = io_write_handler;
665
  return 1; // address mapped successfully
666
}
667
 
668
bx_bool bx_devices_c::register_io_read_handler_range(void *this_ptr, bx_read_handler_t f,
669
                                             Bit32u begin_addr, Bit32u end_addr,
670
                                             const char *name, Bit8u mask)
671
{
672
  Bit32u addr;
673
  begin_addr &= 0x0000ffff;
674
  end_addr &= 0x0000ffff;
675
 
676
  if (end_addr < begin_addr) {
677
    BX_ERROR(("!!! end_addr < begin_addr !!!"));
678
    return 0;
679
  }
680
 
681
  if (!f) {
682
    BX_ERROR(("!!! f == NULL !!!"));
683
    return 0;
684
  }
685
 
686
  /* first check if the port already has a handlers != the default handler */
687
  for (addr = begin_addr; addr <= end_addr; addr++)
688
    if (read_port_to_handler[addr] &&
689
        read_port_to_handler[addr] != &io_read_handlers) { // the default
690
      BX_ERROR(("IO device address conflict(read) at IO address %Xh",
691
                (unsigned) addr));
692
      BX_ERROR(("  conflicting devices: %s & %s",
693
                read_port_to_handler[addr]->handler_name, name));
694
      return 0;
695
  }
696
 
697
  /* first find existing handle for function or create new one */
698
  struct io_handler_struct *curr = &io_read_handlers;
699
  struct io_handler_struct *io_read_handler = NULL;
700
  do {
701
    if (curr->funct == f &&
702
        curr->mask == mask &&
703
        curr->this_ptr == this_ptr &&
704
        curr->handler_name == name) {
705
      io_read_handler = curr;
706
      break;
707
    }
708
    curr = curr->next;
709
  } while (curr->next != &io_read_handlers);
710
 
711
  if (!io_read_handler) {
712
    io_read_handler = new struct io_handler_struct;
713
    io_read_handler->funct = (void *)f;
714
    io_read_handler->this_ptr = this_ptr;
715
    io_read_handler->handler_name = new char[strlen(name)+1];
716
    strcpy(io_read_handler->handler_name, name);
717
    io_read_handler->mask = mask;
718
    io_read_handler->usage_count = 0;
719
    // add the handler to the double linked list of handlers
720
    io_read_handlers.prev->next = io_read_handler;
721
    io_read_handler->next = &io_read_handlers;
722
    io_read_handler->prev = io_read_handlers.prev;
723
    io_read_handlers.prev = io_read_handler;
724
  }
725
 
726
  io_read_handler->usage_count += end_addr - begin_addr + 1;
727
  for (addr = begin_addr; addr <= end_addr; addr++)
728
          read_port_to_handler[addr] = io_read_handler;
729
  return 1; // address mapped successfully
730
}
731
 
732
bx_bool bx_devices_c::register_io_write_handler_range(void *this_ptr, bx_write_handler_t f,
733
                                              Bit32u begin_addr, Bit32u end_addr,
734
                                              const char *name, Bit8u mask)
735
{
736
  Bit32u addr;
737
  begin_addr &= 0x0000ffff;
738
  end_addr &= 0x0000ffff;
739
 
740
  if (end_addr < begin_addr) {
741
    BX_ERROR(("!!! end_addr < begin_addr !!!"));
742
    return 0;
743
  }
744
 
745
  if (!f) {
746
    BX_ERROR(("!!! f == NULL !!!"));
747
    return 0;
748
  }
749
 
750
  /* first check if the port already has a handlers != the default handler */
751
  for (addr = begin_addr; addr <= end_addr; addr++)
752
    if (write_port_to_handler[addr] &&
753
        write_port_to_handler[addr] != &io_write_handlers) { // the default
754
      BX_ERROR(("IO device address conflict(read) at IO address %Xh",
755
                (unsigned) addr));
756
      BX_ERROR(("  conflicting devices: %s & %s",
757
                write_port_to_handler[addr]->handler_name, name));
758
      return 0;
759
    }
760
 
761
  /* first find existing handle for function or create new one */
762
  struct io_handler_struct *curr = &io_write_handlers;
763
  struct io_handler_struct *io_write_handler = NULL;
764
  do {
765
    if (curr->funct == f &&
766
        curr->mask == mask &&
767
        curr->this_ptr == this_ptr &&
768
        curr->handler_name == name) {
769
      io_write_handler = curr;
770
      break;
771
    }
772
    curr = curr->next;
773
  } while (curr->next != &io_write_handlers);
774
 
775
  if (!io_write_handler) {
776
    io_write_handler = new struct io_handler_struct;
777
    io_write_handler->funct = (void *)f;
778
    io_write_handler->this_ptr = this_ptr;
779
    io_write_handler->handler_name = new char[strlen(name)+1];
780
    strcpy(io_write_handler->handler_name, name);
781
    io_write_handler->mask = mask;
782
    io_write_handler->usage_count = 0;
783
    // add the handler to the double linked list of handlers
784
    io_write_handlers.prev->next = io_write_handler;
785
    io_write_handler->next = &io_write_handlers;
786
    io_write_handler->prev = io_write_handlers.prev;
787
    io_write_handlers.prev = io_write_handler;
788
  }
789
 
790
  io_write_handler->usage_count += end_addr - begin_addr + 1;
791
  for (addr = begin_addr; addr <= end_addr; addr++)
792
          write_port_to_handler[addr] = io_write_handler;
793
  return 1; // address mapped successfully
794
}
795
 
796
 
797
// Registration of default handlers (mainly be the unmapped device)
798
bx_bool bx_devices_c::register_default_io_read_handler(void *this_ptr, bx_read_handler_t f,
799
                                               const char *name, Bit8u mask)
800
{
801
  io_read_handlers.funct = (void *)f;
802
  io_read_handlers.this_ptr = this_ptr;
803
  if (io_read_handlers.handler_name) {
804
    delete [] io_read_handlers.handler_name;
805
  }
806
  io_read_handlers.handler_name = new char[strlen(name)+1];
807
  strcpy(io_read_handlers.handler_name, name);
808
  io_read_handlers.mask = mask;
809
  return 1;
810
}
811
 
812
bx_bool bx_devices_c::register_default_io_write_handler(void *this_ptr, bx_write_handler_t f,
813
                                                const char *name, Bit8u mask)
814
{
815
  io_write_handlers.funct = (void *)f;
816
  io_write_handlers.this_ptr = this_ptr;
817
  if (io_write_handlers.handler_name) {
818
    delete [] io_write_handlers.handler_name;
819
  }
820
  io_write_handlers.handler_name = new char[strlen(name)+1];
821
  strcpy(io_write_handlers.handler_name, name);
822
  io_write_handlers.mask = mask;
823
  return 1;
824
}
825
 
826
bx_bool bx_devices_c::unregister_io_read_handler(void *this_ptr, bx_read_handler_t f,
827
                                         Bit32u addr, Bit8u mask)
828
{
829
  addr &= 0x0000ffff;
830
 
831
  struct io_handler_struct *io_read_handler = read_port_to_handler[addr];
832
 
833
  //BX_INFO(("Unregistering I/O read handler at %#x", addr));
834
 
835
  if (!io_read_handler) {
836
    BX_ERROR((">>> NO IO_READ_HANDLER <<<"));
837
    return 0;
838
  }
839
 
840
  if (io_read_handler == &io_read_handlers) {
841
    BX_ERROR((">>> CANNOT UNREGISTER THE DEFAULT IO_READ_HANDLER <<<"));
842
    return 0; // cannot unregister the default handler
843
  }
844
 
845
  if (io_read_handler->funct != f) {
846
    BX_ERROR((">>> NOT THE SAME IO_READ_HANDLER FUNC <<<"));
847
    return 0;
848
  }
849
 
850
  if (io_read_handler->this_ptr != this_ptr) {
851
    BX_ERROR((">>> NOT THE SAME IO_READ_HANDLER THIS_PTR <<<"));
852
    return 0;
853
  }
854
 
855
  if (io_read_handler->mask != mask) {
856
    BX_ERROR((">>> NOT THE SAME IO_READ_HANDLER MASK <<<"));
857
    return 0;
858
  }
859
 
860
  read_port_to_handler[addr] = &io_read_handlers; // reset to default
861
  io_read_handler->usage_count--;
862
 
863
  if (!io_read_handler->usage_count) { // kill this handler entry
864
    io_read_handler->prev->next = io_read_handler->next;
865
    io_read_handler->next->prev = io_read_handler->prev;
866
    delete [] io_read_handler->handler_name;
867
    delete io_read_handler;
868
  }
869
  return 1;
870
}
871
 
872
bx_bool bx_devices_c::unregister_io_write_handler(void *this_ptr, bx_write_handler_t f,
873
                                          Bit32u addr, Bit8u mask)
874
{
875
  addr &= 0x0000ffff;
876
 
877
  struct io_handler_struct *io_write_handler = write_port_to_handler[addr];
878
 
879
  if (!io_write_handler)
880
    return 0;
881
 
882
  if (io_write_handler == &io_write_handlers)
883
    return 0; // cannot unregister the default handler
884
 
885
  if (io_write_handler->funct != f)
886
    return 0;
887
 
888
  if (io_write_handler->this_ptr != this_ptr)
889
    return 0;
890
 
891
  if (io_write_handler->mask != mask)
892
    return 0;
893
 
894
  write_port_to_handler[addr] = &io_write_handlers; // reset to default
895
  io_write_handler->usage_count--;
896
 
897
  if (!io_write_handler->usage_count) { // kill this handler entry
898
    io_write_handler->prev->next = io_write_handler->next;
899
    io_write_handler->next->prev = io_write_handler->prev;
900
    delete [] io_write_handler->handler_name;
901
    delete io_write_handler;
902
  }
903
  return 1;
904
}
905
 
906
bx_bool bx_devices_c::unregister_io_read_handler_range(void *this_ptr, bx_read_handler_t f,
907
                                               Bit32u begin, Bit32u end, Bit8u mask)
908
{
909
  begin &= 0x0000ffff;
910
  end &= 0x0000ffff;
911
  Bit32u addr;
912
  bx_bool ret = 1;
913
 
914
  /*
915
   * the easy way this time
916
   */
917
  for (addr = begin; addr <= end; addr++)
918
    if (!unregister_io_read_handler(this_ptr, f, addr, mask))
919
      ret = 0;
920
 
921
  return ret;
922
}
923
 
924
bx_bool bx_devices_c::unregister_io_write_handler_range(void *this_ptr, bx_write_handler_t f,
925
                                                Bit32u begin, Bit32u end, Bit8u mask)
926
{
927
  begin &= 0x0000ffff;
928
  end &= 0x0000ffff;
929
  Bit32u addr;
930
  bx_bool ret = 1;
931
 
932
  /*
933
   * the easy way this time
934
   */
935
  for (addr = begin; addr <= end; addr++)
936
    if (!unregister_io_write_handler(this_ptr, f, addr, mask))
937
      ret = 0;
938
 
939
  return ret;
940
}
941
 
942
 
943
/*
944
 * Read a byte of data from the IO memory address space
945
 */
946
 
947
  Bit32u BX_CPP_AttrRegparmN(2)
948
bx_devices_c::inp(Bit16u addr, unsigned io_len)
949
{
950
  struct io_handler_struct *io_read_handler;
951
  Bit32u ret;
952
 
953
  BX_INSTR_INP(addr, io_len);
954
 
955
  io_read_handler = read_port_to_handler[addr];
956
  if (io_read_handler->mask & io_len) {
957
        ret = ((bx_read_handler_t)io_read_handler->funct)(io_read_handler->this_ptr, (Bit32u)addr, io_len);
958
  } else {
959
    switch (io_len) {
960
      case 1: ret = 0xff; break;
961
      case 2: ret = 0xffff; break;
962
      default: ret = 0xffffffff; break;
963
    }
964
    if (addr != 0x0cf8) { // don't flood the logfile when probing PCI
965
      BX_ERROR(("read from port 0x%04x with len %d returns 0x%x", addr, io_len, ret));
966
    }
967
  }
968
  BX_INSTR_INP2(addr, io_len, ret);
969
  BX_DBG_IO_REPORT(addr, io_len, BX_READ, ret);
970
  return(ret);
971
}
972
 
973
 
974
/*
975
 * Write a byte of data to the IO memory address space.
976
 */
977
 
978
  void BX_CPP_AttrRegparmN(3)
979
bx_devices_c::outp(Bit16u addr, Bit32u value, unsigned io_len)
980
{
981
  struct io_handler_struct *io_write_handler;
982
 
983
  BX_INSTR_OUTP(addr, io_len);
984
  BX_INSTR_OUTP2(addr, io_len, value);
985
 
986
  BX_DBG_IO_REPORT(addr, io_len, BX_WRITE, value);
987
 
988
  io_write_handler = write_port_to_handler[addr];
989
  if (io_write_handler->mask & io_len) {
990
        ((bx_write_handler_t)io_write_handler->funct)(io_write_handler->this_ptr, (Bit32u)addr, value, io_len);
991
  } else if (addr != 0x0cf8) { // don't flood the logfile when probing PCI
992
    BX_ERROR(("write to port 0x%04x with len %d ignored", addr, io_len));
993
  }
994
}
995
 
996
bx_bool bx_devices_c::is_serial_enabled(void)
997
{
998
  char pname[24];
999
 
1000
  for (int i=0; i<BX_N_SERIAL_PORTS; i++) {
1001
    sprintf(pname, "ports.serial.%d.enabled", i+1);
1002
    if (SIM->get_param_bool(pname)->get())
1003
      return true;
1004
  }
1005
  return false;
1006
}
1007
 
1008
bx_bool bx_devices_c::is_usb_enabled(void)
1009
{
1010
  char pname[20];
1011
 
1012
  for (int i=0; i<BX_N_USB_HUBS; i++) {
1013
    sprintf(pname, "ports.usb.%d.enabled", i+1);
1014
    if (SIM->get_param_bool(pname)->get())
1015
       return true;
1016
  }
1017
  return false;
1018
}
1019
 
1020
bx_bool bx_devices_c::is_parallel_enabled(void)
1021
{
1022
  char pname[26];
1023
 
1024
  for (int i=0; i<BX_N_PARALLEL_PORTS; i++) {
1025
    sprintf(pname, "ports.parallel.%d.enabled", i+1);
1026
    if (SIM->get_param_bool(pname)->get())
1027
      return true;
1028
  }
1029
  return false;
1030
}
1031
 
1032
void bx_pci_device_stub_c::register_pci_state(bx_list_c *list, Bit8u *pci_conf)
1033
{
1034
  char name[6];
1035
 
1036
  bx_list_c *pci = new bx_list_c(list, "pci_conf", 256);
1037
  for (unsigned i=0; i<256; i++) {
1038
    sprintf(name, "0x%02x", i);
1039
    new bx_shadow_num_c(pci, name, &pci_conf[i], BASE_HEX);
1040
  }
1041
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.