Some work on the PCI devices code.

- Added INT pin init to method init_pci_conf().
- Moved readonly register handling to the common PCI write handler.
- Moved IRQ line reporting to the common PCI write handler.
This commit is contained in:
Volker Ruppert 2018-02-04 18:17:28 +00:00
parent 87145baf61
commit 50c1370216
18 changed files with 43 additions and 105 deletions

View File

@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2006-2017 The Bochs Project
// Copyright (C) 2006-2018 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@ -138,8 +138,7 @@ void bx_acpi_ctrl_c::init(void)
BX_ACPI_THIS s.sm_base = 0x0;
// initialize readonly registers
init_pci_conf(0x8086, 0x7113, 0x03, 0x068000, 0x00);
BX_ACPI_THIS pci_conf[0x3d] = BX_PCI_INTA;
init_pci_conf(0x8086, 0x7113, 0x03, 0x068000, 0x00, BX_PCI_INTA);
}
void bx_acpi_ctrl_c::reset(unsigned type)
@ -493,12 +492,6 @@ void bx_acpi_ctrl_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io_
break;
case 0x06: // disallowing write to status lo-byte (is that expected?)
break;
case 0x3c:
if (value8 != oldval) {
BX_INFO(("new irq line = %d", value8));
}
goto set_value;
break;
case 0x40:
value8 = (value8 & 0xc0) | 0x01;
case 0x41:

View File

@ -502,11 +502,7 @@ void bx_devices_c::write(Bit32u address, Bit32u value, unsigned io_len)
Bit8u regnum = (BX_DEV_THIS pci.confAddr & 0xfc) + (address & 0x03);
Bit32u handle = BX_DEV_THIS pci.handler_id[devfunc];
if ((io_len <= 4) && (handle < BX_MAX_PCI_DEVICES)) {
if (((regnum>=4) && (regnum<=7)) || (regnum==12) || (regnum==13) || (regnum>14)) {
BX_DEV_THIS pci.pci_handler[handle].handler->pci_write_handler_common(regnum, value, io_len);
}
else
BX_DEBUG(("read only register, write ignored"));
BX_DEV_THIS pci.pci_handler[handle].handler->pci_write_handler_common(regnum, value, io_len);
}
}
break;
@ -1297,7 +1293,8 @@ bx_bool bx_devices_c::pci_set_base_io(void *this_ptr, bx_read_handler_t f1, bx_w
#undef LOG_THIS
#define LOG_THIS
void bx_pci_device_c::init_pci_conf(Bit16u vid, Bit16u did, Bit8u rev, Bit32u classc, Bit8u headt)
void bx_pci_device_c::init_pci_conf(Bit16u vid, Bit16u did, Bit8u rev,
Bit32u classc, Bit8u headt, Bit8u intpin)
{
memset(pci_conf, 0, 256);
pci_conf[0x00] = (Bit8u)(vid & 0xff);
@ -1309,6 +1306,7 @@ void bx_pci_device_c::init_pci_conf(Bit16u vid, Bit16u did, Bit8u rev, Bit32u cl
pci_conf[0x0a] = (Bit8u)((classc >> 8) & 0xff);
pci_conf[0x0b] = (Bit8u)((classc >> 16) & 0xff);
pci_conf[0x0e] = headt;
pci_conf[0x3d] = intpin;
}
void bx_pci_device_c::init_bar_io(Bit8u num, Bit16u size, bx_read_handler_t rh,
@ -1424,12 +1422,18 @@ void bx_pci_device_c::load_pci_rom(const char *path)
BX_INFO(("loaded PCI ROM '%s' (size=%u / PCI=%uk)", path, (unsigned) stat_buf.st_size, pci_rom_size >> 10));
}
// pci configuration space write callback handler (common)
// pci configuration space write callback handler (common registers)
void bx_pci_device_c::pci_write_handler_common(Bit8u address, Bit32u value, unsigned io_len)
{
Bit8u bnum, value8, oldval;
bx_bool bar_change = 0, rom_change = 0;
if ((address < 4) || ((address > 7) && (address < 12)) || (address == 14) ||
(address == 0x3d)) {
BX_DEBUG(("read only register, write ignored"));
return;
}
if ((address >= 0x10) && (address < 0x28)) {
bnum = ((address - 0x10) >> 2);
if (pci_bar[bnum].type != BX_PCI_BAR_TYPE_NONE) {
@ -1479,6 +1483,13 @@ void bx_pci_device_c::pci_write_handler_common(Bit8u address, Bit32u value, unsi
BX_INFO(("new ROM address = 0x%08x", pci_rom_address));
}
}
} else if (address == 0x3c) {
if (value != pci_conf[0x3c]) {
if (pci_conf[0x3d] != 0) {
BX_INFO(("new IRQ line = %d", value));
}
pci_conf[0x3c] = (Bit8u)value;
}
} else {
pci_write_handler(address, value, io_len);
}

View File

@ -138,10 +138,8 @@ void bx_banshee_c::init_model(void)
}
DEV_register_pci_handlers(this, &s.devfunc, BX_PLUGIN_VOODOO,
"Experimental 3dfx Voodoo Banshee");
init_pci_conf(0x121a, 0x0003, 0x01, 0x030000, 0x00);
init_pci_conf(0x121a, 0x0003, 0x01, 0x030000, 0x00, BX_PCI_INTA);
pci_conf[0x14] = 0x08;
pci_conf[0x18] = 0x01;
pci_conf[0x3d] = BX_PCI_INTA;
init_bar_mem(0, 0x2000000, mem_read_handler, mem_write_handler);
init_bar_mem(1, 0x2000000, mem_read_handler, mem_write_handler);
init_bar_io(2, 256, read_handler, write_handler, &banshee_iomask[0]);
@ -422,11 +420,6 @@ void bx_banshee_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io_le
case 0x04:
value8 &= 0x23;
break;
case 0x3c:
if (value8 != oldval) {
BX_INFO(("new irq line = %d", value8));
}
break;
case 0x2c:
case 0x2d:
case 0x2e:

View File

@ -2313,7 +2313,7 @@ void bx_svga_cirrus_c::svga_init_pcihandlers(void)
// initialize readonly registers
BX_CIRRUS_THIS init_pci_conf(PCI_VENDOR_CIRRUS, PCI_DEVICE_CLGD5446, 0x00,
(PCI_CLASS_BASE_DISPLAY << 16) | (PCI_CLASS_SUB_VGA << 8),
PCI_CLASS_HEADERTYPE_00h);
PCI_CLASS_HEADERTYPE_00h, 0);
BX_CIRRUS_THIS pci_conf[0x04] = (PCI_COMMAND_IOACCESS | PCI_COMMAND_MEMACCESS);
BX_CIRRUS_THIS pci_conf[0x10] =

View File

@ -150,7 +150,7 @@ bx_bool bx_vga_c::init_vga_extension(void)
// Note that the values for vendor and device id are selected at random!
// There might actually be "real" values for "experimental" vendor and
// device that should be used!
init_pci_conf(0x1234, 0x1111, 0x00, 0x030000, 0x00);
init_pci_conf(0x1234, 0x1111, 0x00, 0x030000, 0x00, 0);
if (BX_VGA_THIS vbe_present) {
BX_VGA_THIS pci_conf[0x10] = 0x08;

View File

@ -845,12 +845,11 @@ void bx_voodoo_1_2_c::init_model(void)
DEV_register_pci_handlers(this, &s.devfunc, BX_PLUGIN_VOODOO,
"Experimental 3dfx Voodoo Graphics (SST-1/2)");
if (s.model == VOODOO_1) {
init_pci_conf(0x121a, 0x0001, 0x02, 0x000000, 0x00);
init_pci_conf(0x121a, 0x0001, 0x02, 0x000000, 0x00, BX_PCI_INTA);
} else if (s.model == VOODOO_2) {
init_pci_conf(0x121a, 0x0002, 0x02, 0x038000, 0x00);
init_pci_conf(0x121a, 0x0002, 0x02, 0x038000, 0x00, BX_PCI_INTA);
pci_conf[0x10] = 0x08;
}
pci_conf[0x3d] = BX_PCI_INTA;
init_bar_mem(0, 0x1000000, mem_read_handler, mem_write_handler);
s.vdraw.clock_enabled = 1;
s.vdraw.output_on = 0;
@ -1071,11 +1070,6 @@ void bx_voodoo_1_2_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io
case 0x04:
value8 &= 0x02;
break;
case 0x3c:
if (value8 != oldval) {
BX_INFO(("new irq line = %d", value8));
}
break;
case 0x40:
case 0x41:
case 0x42:

View File

@ -124,7 +124,8 @@ public:
virtual void pci_write_handler(Bit8u address, Bit32u value, unsigned io_len) {}
virtual void pci_bar_change_notify(void) {}
void init_pci_conf(Bit16u vid, Bit16u did, Bit8u rev, Bit32u classc, Bit8u headt);
void init_pci_conf(Bit16u vid, Bit16u did, Bit8u rev, Bit32u classc,
Bit8u headt, Bit8u intpin);
void init_bar_io(Bit8u num, Bit16u size, bx_read_handler_t rh,
bx_write_handler_t wh, const Bit8u *mask);
void init_bar_mem(Bit8u num, Bit32u size, memory_handler_t rh, memory_handler_t wh);

View File

@ -460,8 +460,7 @@ void bx_e1000_c::init(void)
"Intel(R) Gigabit Ethernet");
// initialize readonly registers
init_pci_conf(0x8086, 0x100e, 0x03, 0x020000, 0x00);
BX_E1000_THIS pci_conf[0x3d] = BX_PCI_INTA;
init_pci_conf(0x8086, 0x100e, 0x03, 0x020000, 0x00, BX_PCI_INTA);
BX_E1000_THIS init_bar_mem(0, 0x20000, mem_read_handler, mem_write_handler);
BX_E1000_THIS init_bar_io(1, 64, read_handler, write_handler, &e1000_iomask[0]);
@ -1464,11 +1463,6 @@ void bx_e1000_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io_len)
case 0x04:
value8 &= 0x07;
break;
case 0x3c:
if (value8 != oldval) {
BX_INFO(("new irq line = %d", value8));
}
break;
default:
value8 = oldval;
}

View File

@ -199,11 +199,9 @@ void bx_ne2k_c::init(void)
BX_PLUGIN_NE2K, devname);
// initialize readonly registers
init_pci_conf(0x10ec, 0x8029, 0x00, 0x020000, 0x00);
init_pci_conf(0x10ec, 0x8029, 0x00, 0x020000, 0x00, BX_PCI_INTA);
BX_NE2K_THIS pci_conf[0x04] = 0x01;
BX_NE2K_THIS pci_conf[0x07] = 0x02;
BX_NE2K_THIS pci_conf[0x10] = 0x01;
BX_NE2K_THIS pci_conf[0x3d] = BX_PCI_INTA;
init_bar_io(0, 32, read_handler, write_handler, &ne2k_iomask[0]);
BX_NE2K_THIS s.base_address = 0x0;
BX_NE2K_THIS pci_rom_address = 0;
@ -1701,11 +1699,6 @@ void bx_ne2k_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io_len)
case 0x04:
value8 &= 0x03;
break;
case 0x3c:
if (value8 != oldval) {
BX_INFO(("new irq line = %d", value8));
}
break;
default:
value8 = oldval;
}

View File

@ -156,8 +156,7 @@ void bx_pcipnic_c::init(void)
"Experimental PCI Pseudo NIC");
// initialize readonly registers
init_pci_conf(PNIC_PCI_VENDOR, PNIC_PCI_DEVICE, 0x01, 0x020000, 0x00);
BX_PNIC_THIS pci_conf[0x3d] = BX_PCI_INTA;
init_pci_conf(PNIC_PCI_VENDOR, PNIC_PCI_DEVICE, 0x01, 0x020000, 0x00, BX_PCI_INTA);
BX_PNIC_THIS s.statusbar_id = bx_gui->register_statusitem("PNIC", 1);
@ -397,11 +396,6 @@ void bx_pcipnic_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io_le
case 0x04:
value8 &= 0x01;
break;
case 0x3c:
if (value8 != oldval) {
BX_INFO(("new irq line = %d", value8));
}
break;
default:
value8 = oldval;
}

View File

@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002-2017 The Bochs Project
// Copyright (C) 2002-2018 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@ -78,9 +78,9 @@ void bx_pci_bridge_c::init(void)
// initialize readonly registers
if (BX_PCI_THIS chipset == BX_PCI_CHIPSET_I440FX) {
init_pci_conf(0x8086, 0x1237, 0x00, 0x060000, 0x00);
init_pci_conf(0x8086, 0x1237, 0x00, 0x060000, 0x00, 0);
} else {
init_pci_conf(0x8086, 0x0122, 0x02, 0x060000, 0x00);
init_pci_conf(0x8086, 0x0122, 0x02, 0x060000, 0x00, 0);
}
// DRAM module setup

View File

@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002-2017 The Bochs Project
// Copyright (C) 2002-2018 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@ -97,9 +97,9 @@ void bx_piix3_c::init(void)
}
// initialize readonly registers
if (BX_P2I_THIS s.chipset == BX_PCI_CHIPSET_I440FX) {
init_pci_conf(0x8086, 0x7000, 0x00, 0x060100, 0x80);
init_pci_conf(0x8086, 0x7000, 0x00, 0x060100, 0x80, 0);
} else {
init_pci_conf(0x8086, 0x122e, 0x01, 0x060100, 0x80);
init_pci_conf(0x8086, 0x122e, 0x01, 0x060100, 0x80, 0);
}
BX_P2I_THIS pci_conf[0x04] = 0x07;
// irq routing registers

View File

@ -97,9 +97,9 @@ void bx_pci_ide_c::init(void)
BX_PIDE_THIS s.chipset = SIM->get_param_enum(BXPN_PCI_CHIPSET)->get();
// initialize readonly registers
if (BX_PIDE_THIS s.chipset == BX_PCI_CHIPSET_I440FX) {
init_pci_conf(0x8086, 0x7010, 0x00, 0x010180, 0x00);
init_pci_conf(0x8086, 0x7010, 0x00, 0x010180, 0x00, 0);
} else {
init_pci_conf(0x8086, 0x1230, 0x00, 0x010180, 0x00);
init_pci_conf(0x8086, 0x1230, 0x00, 0x010180, 0x00, 0);
}
BX_PIDE_THIS init_bar_io(4, 16, read_handler, write_handler, &bmdma_iomask[0]);
}

View File

@ -253,8 +253,7 @@ void bx_es1370_c::init(void)
"ES1370 soundcard");
// initialize readonly registers
init_pci_conf(0x1274, 0x5000, 0x00, 0x040100, 0x00);
BX_ES1370_THIS pci_conf[0x3d] = BX_PCI_INTA;
init_pci_conf(0x1274, 0x5000, 0x00, 0x040100, 0x00, BX_PCI_INTA);
BX_ES1370_THIS init_bar_io(0, 64, read_handler, write_handler, &es1370_iomask[0]);
@ -1106,12 +1105,6 @@ void bx_es1370_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io_len
case 0x3d: //
case 0x06: // disallowing write to status lo-byte (is that expected?)
break;
case 0x3c:
if (value8 != oldval) {
BX_INFO(("new irq line = %d", value8));
BX_ES1370_THIS pci_conf[address+i] = value8;
}
break;
default:
BX_ES1370_THIS pci_conf[address+i] = value8;
}

View File

@ -85,8 +85,7 @@ void bx_uhci_core_c::init_uhci(Bit8u devfunc, Bit16u devid, Bit8u headt, Bit8u i
"USB UHCI");
// initialize readonly registers
init_pci_conf(0x8086, devid, 0x01, 0x0c0300, headt);
pci_conf[0x3d] = intp;
init_pci_conf(0x8086, devid, 0x01, 0x0c0300, headt, intp);
init_bar_io(4, 32, read_handler, write_handler, &uhci_iomask[0]);
for (int i=0; i<USB_UHCI_PORTS; i++) {
@ -913,12 +912,6 @@ void bx_uhci_core_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io_
case 0x05: // disallowing write to command hi-byte
case 0x06: // disallowing write to status lo-byte (is that expected?)
break;
case 0x3c:
if (value8 != oldval) {
BX_INFO(("new irq line = %d", value8));
pci_conf[address+i] = value8;
}
break;
default:
pci_conf[address+i] = value8;
}

View File

@ -245,8 +245,7 @@ void bx_usb_ehci_c::init(void)
// 0x8086 = vendor (Intel)
// 0x24cd = device (82801D)
// revision number (0x10)
init_pci_conf(0x8086, 0x24cd, 0x10, 0x0c0320, 0x00);
BX_EHCI_THIS pci_conf[0x3d] = BX_PCI_INTD;
init_pci_conf(0x8086, 0x24cd, 0x10, 0x0c0320, 0x00, BX_PCI_INTD);
BX_EHCI_THIS pci_conf[0x60] = 0x20;
BX_EHCI_THIS init_bar_mem(0, IO_SPACE_SIZE, read_handler, write_handler);
@ -2257,12 +2256,6 @@ void bx_usb_ehci_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io_l
case 0x3f: //
case 0x60: //
break;
case 0x3c:
if (value8 != oldval) {
BX_INFO(("new irq line = %d", value8));
BX_EHCI_THIS pci_conf[address+i] = value8;
}
break;
case 0x2c:
case 0x2d:
case 0x2e:

View File

@ -181,7 +181,7 @@ void bx_usb_ohci_c::init(void)
"USB OHCI");
// initialize readonly registers
init_pci_conf(0x11c1, 0x5803, 0x11, 0x0c0310, 0x00);
init_pci_conf(0x11c1, 0x5803, 0x11, 0x0c0310, 0x00, BX_PCI_INTD);
BX_OHCI_THIS init_bar_mem(0, 4096, read_handler, write_handler);
BX_OHCI_THIS hub.ohci_done_count = 7;
@ -234,7 +234,6 @@ void bx_usb_ohci_c::reset(unsigned type)
{ 0x34, 0x50 }, // offset of capabilities list within configuration space
{ 0x3c, 0x0B }, // IRQ
{ 0x3d, BX_PCI_INTD }, // INT
{ 0x3E, 0x03 }, // minimum time bus master needs PCI bus ownership, in 250ns units
{ 0x3F, 0x56 }, // maximum latency, in 250ns units (bus masters only) (read-only)
@ -1454,12 +1453,6 @@ void bx_usb_ohci_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io_l
case 0x05: // disallowing write to command hi-byte
case 0x06: // disallowing write to status lo-byte (is that expected?)
break;
case 0x3c:
if (value8 != oldval) {
BX_INFO(("new irq line = %d", value8));
BX_OHCI_THIS pci_conf[address+i] = value8;
}
break;
default:
BX_OHCI_THIS pci_conf[address+i] = value8;
}

View File

@ -267,8 +267,7 @@ void bx_usb_xhci_c::init(void)
// 0x1912 = vendor (Renesas)
// 0x0015 = device (0x0014 = uPD720201, 0x0015 = uPD720202)
// revision number (0x03 = uPD720201, 0x02 = uPD720202)
init_pci_conf(0x1912, 0x0015, 0x02, 0x0c0330, 0x00);
BX_XHCI_THIS pci_conf[0x3d] = BX_PCI_INTD;
init_pci_conf(0x1912, 0x0015, 0x02, 0x0c0330, 0x00, BX_PCI_INTD);
BX_XHCI_THIS init_bar_mem(0, IO_SPACE_SIZE, read_handler, write_handler);
// initialize capability registers
@ -3126,12 +3125,6 @@ void bx_usb_xhci_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io_l
case 0x05: // disallowing write to command hi-byte
case 0x06: // disallowing write to status lo-byte (is that expected?)
break;
case 0x3c:
if (value8 != oldval) {
BX_INFO(("new irq line = %d", value8));
BX_XHCI_THIS pci_conf[address+i] = value8;
}
break;
case 0x54:
if ((((value8 & 0x03) == 0x03) && ((BX_XHCI_THIS pci_conf[address+i] & 0x03) == 0x00)) &&
(BX_XHCI_THIS hub.op_regs.HcCommand.rs || !BX_XHCI_THIS hub.op_regs.HcStatus.hch))