diff --git a/src/i430fx.c b/src/i430fx.c index d56f06bd9..b00a63588 100644 --- a/src/i430fx.c +++ b/src/i430fx.c @@ -181,7 +181,7 @@ static void i430fx_pci_reset(void) void i430fx_init(void) { - pci_add_specific(0, i430fx_read, i430fx_write, NULL); + pci_add_card(0, i430fx_read, i430fx_write, NULL); i430fx_reset(); diff --git a/src/i430hx.c b/src/i430hx.c index 860d9a814..9fed7c5bf 100644 --- a/src/i430hx.c +++ b/src/i430hx.c @@ -169,7 +169,7 @@ static void i430hx_pci_reset(void) void i430hx_init(void) { - pci_add_specific(0, i430hx_read, i430hx_write, NULL); + pci_add_card(0, i430hx_read, i430hx_write, NULL); i430hx_reset(); diff --git a/src/i430lx.c b/src/i430lx.c index 8c4cb64ff..087c0295c 100644 --- a/src/i430lx.c +++ b/src/i430lx.c @@ -166,7 +166,7 @@ static void i430lx_pci_reset(void) void i430lx_init(void) { - pci_add_specific(0, i430lx_read, i430lx_write, NULL); + pci_add_card(0, i430lx_read, i430lx_write, NULL); i430lx_reset(); diff --git a/src/i430nx.c b/src/i430nx.c index 0322edfb2..bf9225956 100644 --- a/src/i430nx.c +++ b/src/i430nx.c @@ -164,7 +164,7 @@ static void i430nx_pci_reset(void) void i430nx_init(void) { - pci_add_specific(0, i430nx_read, i430nx_write, NULL); + pci_add_card(0, i430nx_read, i430nx_write, NULL); i430nx_reset(); diff --git a/src/i430vx.c b/src/i430vx.c index 8b39d09de..7d0c6ce2a 100644 --- a/src/i430vx.c +++ b/src/i430vx.c @@ -172,7 +172,7 @@ static void i430vx_pci_reset(void) void i430vx_init(void) { - pci_add_specific(0, i430vx_read, i430vx_write, NULL); + pci_add_card(0, i430vx_read, i430vx_write, NULL); i430vx_reset(); diff --git a/src/i440fx.c b/src/i440fx.c index d47175a48..3c739657e 100644 --- a/src/i440fx.c +++ b/src/i440fx.c @@ -173,7 +173,7 @@ static void i440fx_pci_reset(void) void i440fx_init(void) { - pci_add_specific(0, i440fx_read, i440fx_write, NULL); + pci_add_card(0, i440fx_read, i440fx_write, NULL); i440fx_reset(); diff --git a/src/model.c b/src/model.c index 48e161d32..3b2e71ca8 100644 --- a/src/model.c +++ b/src/model.c @@ -50,6 +50,9 @@ #include "nvr.h" #include "pc87306.h" #include "pci.h" +#if 0 +#include "pci_dummy.h" +#endif #include "pic.h" #include "piix.h" #include "pit.h" @@ -715,9 +718,11 @@ static void at_sis496_init(void) at_ide_init(); memregs_init(); pci_init(PCI_CONFIG_TYPE_1); - pci_slot(0xb); - pci_slot(0xd); - pci_slot(0xf); + pci_register_slot(0x05, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x07, PCI_CARD_NORMAL, 4, 1, 2, 3); sis496_init(); trc_init(); } @@ -735,10 +740,13 @@ static void at_premiere_common_init(void) at_ide_init(); memregs_init(); pci_init(PCI_CONFIG_TYPE_2); - pci_slot(0xc); - pci_slot(0xe); - pci_slot(0x6); - sio_init(2, 0xc, 0xe, 0x6, 0); + pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x06, PCI_CARD_NORMAL, 3, 2, 1, 4); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 1, 3, 4); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 3, 2, 4); + pci_register_slot(0x02, PCI_CARD_SPECIAL, 0, 0, 0, 0); + sio_init(2); fdc37c665_init(); intel_batman_init(); device_add(&intel_flash_bxt_ami_device); @@ -762,7 +770,7 @@ static void at_586mc1_init(void) pci_slot(0xc); pci_slot(0xe); pci_slot(0x6); - sio_init(2, 0xc, 0xe, 0x6, 0); + sio_init(2); device_add(&intel_flash_bxt_device); secondary_ide_check(); } @@ -781,12 +789,15 @@ static void at_endeavor_init(void) at_ide_init(); memregs_init(); pci_init(PCI_CONFIG_TYPE_1); - pci_slot(0xd); - pci_slot(0xe); - pci_slot(0xf); - pci_slot(0x10); + pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x08, PCI_CARD_ONBOARD, 4, 0, 0, 0); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x10, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); i430fx_init(); - piix_init(7, 0xd, 0xe, 0xf, 0x10); + piix_init(7); pc87306_init(); device_add(&intel_flash_bxt_ami_device); } @@ -797,11 +808,13 @@ static void at_zappa_init(void) at_ide_init(); memregs_init(); pci_init(PCI_CONFIG_TYPE_1); - pci_slot(0xd); - pci_slot(0xf); - pci_slot(0xe); + pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); i430fx_init(); - piix_init(7, 0xd, 0xf, 0xe, 0); + piix_init(7); pc87306_init(); device_add(&intel_flash_bxt_ami_device); } @@ -811,12 +824,14 @@ static void at_mb500n_init(void) { at_ide_init(); pci_init(PCI_CONFIG_TYPE_1); - pci_slot(0x14); - pci_slot(0x13); - pci_slot(0x12); - pci_slot(0x11); + pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x14, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x11, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); i430fx_init(); - piix_init(7, 0x14, 0x13, 0x12, 0x11); + piix_init(7); fdc37c665_init(); device_add(&intel_flash_bxt_device); } @@ -827,15 +842,14 @@ static void at_president_init(void) at_ide_init(); memregs_init(); pci_init(PCI_CONFIG_TYPE_1); - pci_slot(8); - pci_slot(9); - pci_slot(10); - pci_slot(11); + pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); i430fx_init(); - piix_init(7, 8, 9, 10, 11); -#if 0 - superio_detect_init(); -#endif + piix_init(7); w83877f_init(); device_add(&intel_flash_bxt_device); } @@ -846,12 +860,14 @@ static void at_p54tp4xe_init(void) at_ide_init(); memregs_init(); pci_init(PCI_CONFIG_TYPE_1); - pci_slot(12); - pci_slot(11); - pci_slot(10); - pci_slot(9); + pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); i430fx_init(); - piix_init(7, 12, 11, 10, 9); + piix_init(7); fdc37c665_init(); device_add(&intel_flash_bxt_device); } @@ -862,13 +878,15 @@ static void at_thor_init(void) at_ide_init(); memregs_init(); pci_init(PCI_CONFIG_TYPE_1); - pci_slot(8); - pci_slot(0xd); - pci_slot(0xe); - pci_slot(0xf); - pci_slot(0x10); + pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x08, PCI_CARD_ONBOARD, 4, 0, 0, 0); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 2, 1); + pci_register_slot(0x10, PCI_CARD_NORMAL, 4, 3, 2, 1); + pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); i430fx_init(); - piix_init_thor(7, 8, 0xd, 0xf, 0xe, 0x10); + piix_init(7); pc87306_init(); device_add(&intel_flash_bxt_ami_device); } @@ -880,12 +898,15 @@ static void at_ap53_init(void) memregs_init(); powermate_memregs_init(); pci_init(PCI_CONFIG_TYPE_1); - pci_slot(0x11); - pci_slot(0x12); - pci_slot(0x13); - pci_slot(0x14); + pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x06, PCI_CARD_ONBOARD, 1, 2, 3, 4); i430hx_init(); - piix3_init(7, 0x11, 0x12, 0x13, 0x14); + piix3_init(7); fdc37c669_init(); device_add(&intel_flash_bxt_device); } @@ -897,12 +918,14 @@ static void at_p55t2s_init(void) memregs_init(); powermate_memregs_init(); pci_init(PCI_CONFIG_TYPE_1); - pci_slot(0x12); - pci_slot(0x11); - pci_slot(0x14); - pci_slot(0x13); + pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x12, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x13, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x14, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x11, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); i430hx_init(); - piix3_init(7, 0x12, 0x11, 0x14, 0x13); + piix3_init(7); pc87306_init(); device_add(&intel_flash_bxt_device); } @@ -913,12 +936,15 @@ static void at_acerm3a_init(void) at_ide_init(); powermate_memregs_init(); pci_init(PCI_CONFIG_TYPE_1); - pci_slot(0xc); - pci_slot(0xd); - pci_slot(0xe); - pci_slot(0xf); + pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x1F, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x10, PCI_CARD_ONBOARD, 4, 0, 0, 0); i430hx_init(); - piix3_init(7, 0xc, 0xd, 0xe, 0xf); + piix3_init(7); fdc37c932fr_init(); device_add(&intel_flash_bxb_device); } @@ -929,12 +955,15 @@ static void at_acerv35n_init(void) at_ide_init(); powermate_memregs_init(); pci_init(PCI_CONFIG_TYPE_1); - pci_slot(0x11); - pci_slot(0x12); - pci_slot(0x13); - pci_slot(0x14); + pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); i430hx_init(); - piix3_init(7, 0x11, 0x12, 0x13, 0x14); + piix3_init(7); fdc37c932fr_init(); device_add(&intel_flash_bxb_device); } @@ -945,33 +974,35 @@ static void at_p55t2p4_init(void) at_ide_init(); memregs_init(); pci_init(PCI_CONFIG_TYPE_1); - pci_slot(12); - pci_slot(11); - pci_slot(10); - pci_slot(9); + pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); i430hx_init(); - piix3_init(7, 12, 11, 10, 9); + piix3_init(7); w83877f_init(); device_add(&intel_flash_bxt_device); } -#if 0 static void at_i430vx_init(void) { at_ide_init(); memregs_init(); pci_init(PCI_CONFIG_TYPE_1); - pci_slot(0x11); - pci_slot(0x12); - pci_slot(0x13); - pci_slot(0x14); + pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x11, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x12, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); i430vx_init(); - piix3_init(7, 17, 18, 20, 19); + piix3_init(7); um8669f_init(); device_add(&intel_flash_bxt_device); } -#endif static void at_p55tvp4_init(void) @@ -979,42 +1010,31 @@ static void at_p55tvp4_init(void) at_ide_init(); memregs_init(); pci_init(PCI_CONFIG_TYPE_1); - pci_slot(12); - pci_slot(11); - pci_slot(10); - pci_slot(9); + pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); i430vx_init(); - piix3_init(7, 12, 11, 10, 9); + piix3_init(7); w83877f_init(); device_add(&intel_flash_bxt_device); } -static void at_i430vx_init(void) -{ - at_ide_init(); - pci_init(PCI_CONFIG_TYPE_1); - pci_slot(0x11); - pci_slot(0x12); - pci_slot(0x13); - pci_slot(0x14); - i430vx_init(); - piix_init(7, 18, 17, 20, 19); - um8669f_init(); - device_add(&intel_flash_bxt_device); -} - - static void at_p55va_init(void) { at_ide_init(); pci_init(PCI_CONFIG_TYPE_1); - pci_slot(8); - pci_slot(9); - pci_slot(10); - pci_slot(11); + pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); i430vx_init(); - piix3_init(7, 8, 9, 10, 11); + piix3_init(7); fdc37c932fr_init(); device_add(&intel_flash_bxt_device); } @@ -1025,12 +1045,15 @@ static void at_i440fx_init(void) at_ide_init(); memregs_init(); pci_init(PCI_CONFIG_TYPE_1); - pci_slot(0xe); - pci_slot(0xd); - pci_slot(0xc); - pci_slot(0xb); - i430vx_init(); - piix3_init(7, 0xe, 0xd, 0xc, 0xb); + pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); + i440fx_init(); + piix3_init(7); fdc37c665_init(); device_add(&intel_flash_bxt_device); } @@ -1041,12 +1064,15 @@ static void at_s1668_init(void) at_ide_init(); memregs_init(); pci_init(PCI_CONFIG_TYPE_1); - pci_slot(0xe); - pci_slot(0xd); - pci_slot(0xc); - pci_slot(0xb); + pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 1, 2, 3, 4); i440fx_init(); - piix3_init(7, 0xe, 0xd, 0xc, 0xb); + piix3_init(7); fdc37c665_init(); device_add(&intel_flash_bxt_device); } diff --git a/src/network/net_ne2000.c b/src/network/net_ne2000.c index 31255cc65..ecf507583 100644 --- a/src/network/net_ne2000.c +++ b/src/network/net_ne2000.c @@ -49,13 +49,6 @@ #define PCI_REGSIZE 256 /* size of PCI space */ -/* For PCI. */ -typedef union { - uint32_t addr; - uint8_t addr_regs[4]; -} bar_t; - - /* Never completely fill the ne2k ring so that we never hit the unclear completely full buffer condition. */ #define NE2K_NEVER_FULL_RING (1) @@ -2018,7 +2011,7 @@ nic_init(int board) dev->eeprom[0x7D] = (PCI_VENDID>>8); /* Insert this device onto the PCI bus, keep its slot number. */ - dev->card = pci_add(nic_pci_read, nic_pci_write, dev); + dev->card = pci_add_card(PCI_ADD_NORMAL, nic_pci_read, nic_pci_write, dev); } /* Set up our BIA. */ diff --git a/src/pci.c b/src/pci.c index 547de2efb..ee80b63c3 100644 --- a/src/pci.c +++ b/src/pci.c @@ -1,3 +1,5 @@ +#include + #include "ibm.h" #include "io.h" #include "mem.h" @@ -5,19 +7,46 @@ #include "pci.h" -void (*pci_card_write[32])(int func, int addr, uint8_t val, void *priv); -uint8_t (*pci_card_read[32])(int func, int addr, void *priv); -void *pci_priv[32]; -static int pci_irq_routing[32]; -/* static int pci_irq_active[32]; */ -static int pci_irqs[4]; -static int pci_card_valid[32]; static uint64_t pci_irq_hold[16]; +typedef struct +{ + uint8_t id, type; + uint8_t irq_routing[4]; + void (*write) (int func, int addr, uint8_t val, void *priv); + uint8_t (*read) (int func, int addr, void *priv); + void * priv; +} pci_card_t; + +static pci_card_t pci_cards[32]; +static uint8_t last_pci_card = 0; + +static uint8_t pci_card_to_slot_mapping[32]; + +static uint8_t elcr[2] = { 0, 0 }; + +static uint8_t pci_irqs[4]; + static int pci_index, pci_func, pci_card, pci_bus, pci_enable, pci_key; int pci_burst_time, pci_nonburst_time; -void pci_cf8_write(uint16_t port, uint32_t val, void *p) +int pci_do_log = 0; + +void pci_log(const char *format, ...) +{ +#ifdef ENABLE_PCI_LOG + if (pci_do_log) + { + va_list ap; + va_start(ap, format); + vprintf(format, ap); + va_end(ap); + fflush(stdout); + } +#endif +} + +static void pci_cf8_write(uint16_t port, uint32_t val, void *p) { pci_index = val & 0xff; pci_func = (val >> 8) & 7; @@ -26,83 +55,92 @@ void pci_cf8_write(uint16_t port, uint32_t val, void *p) pci_enable = (val >> 31) & 1; } -uint32_t pci_cf8_read(uint16_t port, void *p) +static uint32_t pci_cf8_read(uint16_t port, void *p) { return pci_index | (pci_func << 8) | (pci_card << 11) | (pci_bus << 16) | (pci_enable << 31); } -void pci_write(uint16_t port, uint8_t val, void *priv) +static void pci_write(uint16_t port, uint8_t val, void *priv) { + uint8_t slot = 0; + switch (port) { case 0xcfc: case 0xcfd: case 0xcfe: case 0xcff: if (!pci_enable) return; - if (!pci_bus && pci_card_write[pci_card]) - pci_card_write[pci_card](pci_func, pci_index | (port & 3), val, pci_priv[pci_card]); + if (!pci_bus) + { + slot = pci_card_to_slot_mapping[pci_card]; + if (slot != 0xFF) + { + if (pci_cards[slot].write) + { + /* pci_log("Reading PCI card on slot %02X (pci_cards[%i])...\n", pci_card, slot); */ + pci_cards[slot].write(pci_func, pci_index | (port & 3), val, pci_cards[slot].priv); + } + } + } break; } } -uint8_t pci_read(uint16_t port, void *priv) +static uint8_t pci_read(uint16_t port, void *priv) { + uint8_t slot = 0; + switch (port) { case 0xcfc: case 0xcfd: case 0xcfe: case 0xcff: if (!pci_enable) return 0xff; - if (!pci_bus && pci_card_read[pci_card]) - return pci_card_read[pci_card](pci_func, pci_index | (port & 3), pci_priv[pci_card]); + if (!pci_bus) + { + slot = pci_card_to_slot_mapping[pci_card]; + if (slot != 0xFF) + { + if (pci_cards[slot].read) + { + return pci_cards[slot].read(pci_func, pci_index | (port & 3), pci_cards[slot].priv); + } + } + } return 0xff; } return 0xff; } -uint8_t elcr[2] = { 0, 0 }; - -void elcr_write(uint16_t port, uint8_t val, void *priv) +static void elcr_write(uint16_t port, uint8_t val, void *priv) { - /* pclog("ELCR%i: WRITE %02X\n", port & 1, val); */ + /* pci_log("ELCR%i: WRITE %02X\n", port & 1, val); */ elcr[port & 1] = val; /* printf("ELCR %i: %c %c %c %c %c %c %c %c\n", port & 1, (val & 1) ? 'L' : 'E', (val & 2) ? 'L' : 'E', (val & 4) ? 'L' : 'E', (val & 8) ? 'L' : 'E', (val & 0x10) ? 'L' : 'E', (val & 0x20) ? 'L' : 'E', (val & 0x40) ? 'L' : 'E', (val & 0x80) ? 'L' : 'E'); */ } -uint8_t elcr_read(uint16_t port, void *priv) +static uint8_t elcr_read(uint16_t port, void *priv) { - /* pclog("ELCR%i: READ %02X\n", port & 1, elcr[port & 1]); */ + /* pci_log("ELCR%i: READ %02X\n", port & 1, elcr[port & 1]); */ return elcr[port & 1]; } -void elcr_reset(void) +static void elcr_reset(void) { - int i = 0; - pic_reset(); elcr[0] = elcr[1] = 0; - -#if 0 - for (i = 0; i < 32; i++) - { - pci_irq_active[i] = 0; - } -#endif - - for (i = 0; i < 16; i++) - { - pci_irq_hold[i] = 0; - } } -void pci_type2_write(uint16_t port, uint8_t val, void *priv); -uint8_t pci_type2_read(uint16_t port, void *priv); +static void pci_type2_write(uint16_t port, uint8_t val, void *priv); +static uint8_t pci_type2_read(uint16_t port, void *priv); -void pci_type2_write(uint16_t port, uint8_t val, void *priv) +static void pci_type2_write(uint16_t port, uint8_t val, void *priv) { + uint8_t slot = 0; + if (port == 0xcf8) { pci_func = (val >> 1) & 7; @@ -121,13 +159,24 @@ void pci_type2_write(uint16_t port, uint8_t val, void *priv) pci_card = (port >> 8) & 0xf; pci_index = port & 0xff; - if (!pci_bus && pci_card_write[pci_card]) - pci_card_write[pci_card](pci_func, pci_index | (port & 3), val, pci_priv[pci_card]); + if (!pci_bus) + { + slot = pci_card_to_slot_mapping[pci_card]; + if (slot != 0xFF) + { + if (pci_cards[slot].write) + { + pci_cards[slot].write(pci_func, pci_index | (port & 3), val, pci_cards[slot].priv); + } + } + } } } -uint8_t pci_type2_read(uint16_t port, void *priv) +static uint8_t pci_type2_read(uint16_t port, void *priv) { + uint8_t slot = 0; + if (port == 0xcf8) { return pci_key | (pci_func << 1); @@ -141,8 +190,17 @@ uint8_t pci_type2_read(uint16_t port, void *priv) pci_card = (port >> 8) & 0xf; pci_index = port & 0xff; - if (!pci_bus && pci_card_write[pci_card]) - return pci_card_read[pci_card](pci_func, pci_index | (port & 3), pci_priv[pci_card]); + if (!pci_bus) + { + slot = pci_card_to_slot_mapping[pci_card]; + if (slot != 0xFF) + { + if (pci_cards[slot].read) + { + return pci_cards[slot].read(pci_func, pci_index | (port & 3), pci_cards[slot].priv); + } + } + } } return 0xff; } @@ -152,15 +210,9 @@ void pci_set_irq_routing(int pci_int, int irq) pci_irqs[pci_int - 1] = irq; } -void pci_set_card_routing(int card, int pci_int) -{ - pci_irq_routing[card] = pci_int; -} - -int pci_irq_is_level(int irq) +static int pci_irq_is_level(int irq) { int real_irq = irq & 7; - /* int irq_elcr = 0; */ if (irq > 7) { @@ -174,15 +226,15 @@ int pci_irq_is_level(int irq) void pci_issue_irq(int irq) { - /* pclog("Issuing PCI IRQ %i: ", irq); */ + /* pci_log("Issuing PCI IRQ %i: ", irq); */ if (pci_irq_is_level(irq)) { - /* pclog("Level\n"); */ + /* pci_log("Level\n"); */ picintlevel(1 << irq); } else { - /* pclog("Edge\n"); */ + /* pci_log("Edge\n"); */ picint(1 << irq); } } @@ -208,30 +260,93 @@ void pci_ide_set_irq(int ide_board, int irq) } } -void pci_set_irq(int card, int pci_int) +void pci_set_irq(uint8_t card, uint8_t pci_int) { - int irq = ((pci_int - PCI_INTA) + (pci_irq_routing[card] - PCI_INTA)) & 3; + uint8_t slot = 0; + uint8_t irq_routing = 0; + uint8_t pci_int_index = pci_int - PCI_INTA; + uint8_t irq_line = 0; + uint8_t level = 0; - if (pci_irq_routing[card] && (pci_irqs[irq] != PCI_IRQ_DISABLED)) - { - if (pci_irq_is_level(pci_irqs[irq]) && (pci_irq_hold[pci_irqs[irq]] & (1 << card))) - { - /* IRQ already held, do nothing. */ - return; - } + if (!last_pci_card) + { + pci_log("pci_set_irq(%02X, %02X): No PCI slots (how are we even here?!)\n", card, pci_int); + return; + } + else + { + pci_log("pci_set_irq(%02X, %02X): %i PCI slots\n", card, pci_int, last_pci_card); + } - if (!pci_irq_is_level(pci_irqs[irq]) || !pci_irq_hold[pci_irqs[irq]]) - { - /* Only raise the interrupt if it's edge-triggered or level-triggered and not yet being held. */ - pci_issue_irq(pci_irqs[irq]); - } + slot = pci_card_to_slot_mapping[card]; - /* If the IRQ is level-triggered, mark that this card is holding it. */ - if (pci_irq_is_level(pci_irqs[irq])) - { - pci_irq_hold[pci_irqs[irq]] |= (1 << card); - } - } + if (slot == 0xFF) + { + pci_log("pci_set_irq(%02X, %02X): Card is not on a PCI slot (how are we even here?!)\n", card, pci_int); + return; + } + else + { + pci_log("pci_set_irq(%02X, %02X): Card is on PCI slot %02X\n", card, pci_int, slot); + } + + if (!pci_cards[slot].irq_routing[pci_int_index]) + { + pci_log("pci_set_irq(%02X, %02X): No IRQ routing for this slot and INT pin combination\n", card, pci_int); + return; + } + else + { + irq_routing = (pci_cards[slot].irq_routing[pci_int_index] - PCI_INTA) & 3; + pci_log("pci_set_irq(%02X, %02X): IRQ routing for this slot and INT pin combination: %02X\n", card, pci_int, irq_routing); + } + + if (pci_irqs[irq_routing] > 0x0F) + { + pci_log("pci_set_irq(%02X, %02X): IRQ line is disabled\n", card, pci_int); + return; + } + else + { + irq_line = pci_irqs[irq_routing]; + pci_log("pci_set_irq(%02X, %02X): Using IRQ %i\n", card, pci_int, irq_line); + } + + if (pci_irq_is_level(irq_line) && (pci_irq_hold[irq_line] & (1 << card))) + { + /* IRQ already held, do nothing. */ + pci_log("pci_set_irq(%02X, %02X): Card is already holding the IRQ\n", card, pci_int); + return; + } + else + { + pci_log("pci_set_irq(%02X, %02X): Card not yet holding the IRQ\n", card, pci_int); + } + + level = pci_irq_is_level(irq_line); + + if (!level || !pci_irq_hold[irq_line]) + { + pci_log("pci_set_irq(%02X, %02X): Issuing %s-triggered IRQ (%sheld)\n", card, pci_int, level ? "level" : "edge", pci_irq_hold[irq_line] ? "" : "not "); + + /* Only raise the interrupt if it's edge-triggered or level-triggered and not yet being held. */ + pci_issue_irq(irq_line); + } + else if (level && pci_irq_hold[irq_line]) + { + pci_log("pci_set_irq(%02X, %02X): IRQ line already being held\n", card, pci_int); + } + + /* If the IRQ is level-triggered, mark that this card is holding it. */ + if (pci_irq_is_level(irq_line)) + { + pci_log("pci_set_irq(%02X, %02X): Marking that this card is holding the IRQ\n", card, pci_int); + pci_irq_hold[irq_line] |= (1 << card); + } + else + { + pci_log("pci_set_irq(%02X, %02X): Edge-triggered interrupt, not marking\n", card, pci_int); + } } void pci_ide_clear_irq(int ide_board, int irq) @@ -250,36 +365,87 @@ void pci_ide_clear_irq(int ide_board, int irq) } } -void pci_clear_irq(int card, int pci_int) +void pci_clear_irq(uint8_t card, uint8_t pci_int) { - int irq = ((pci_int - PCI_INTA) + (pci_irq_routing[card] - PCI_INTA)) & 3; + uint8_t slot = 0; + uint8_t irq_routing = 0; + uint8_t pci_int_index = pci_int - PCI_INTA; + uint8_t irq_line = 0; + uint8_t level = 0; - /* Do not clear the interrupt until we're the last card being serviced. */ - if (pci_irq_routing[card] && (pci_irqs[irq] != PCI_IRQ_DISABLED)) - { - /* pclog("Clearing PCI IRQ %i: ", pci_irqs[irq]); */ + if (!last_pci_card) + { + pci_log("pci_clear_irq(%02X, %02X): No PCI slots (how are we even here?!)\n", card, pci_int); + return; + } + else + { + pci_log("pci_clear_irq(%02X, %02X): %i PCI slots\n", card, pci_int, last_pci_card); + } - if (pci_irq_is_level(pci_irqs[irq])) + slot = pci_card_to_slot_mapping[card]; + + if (slot == 0xFF) + { + pci_log("pci_clear_irq(%02X, %02X): Card is not on a PCI slot (how are we even here?!)\n", card, pci_int); + return; + } + else + { + pci_log("pci_clear_irq(%02X, %02X): Card is on PCI slot %02X\n", card, pci_int, slot); + } + + if (!pci_cards[slot].irq_routing[pci_int_index]) + { + pci_log("pci_clear_irq(%02X, %02X): No IRQ routing for this slot and INT pin combination\n", card, pci_int); + return; + } + else + { + irq_routing = (pci_cards[slot].irq_routing[pci_int_index] - PCI_INTA) & 3; + pci_log("pci_clear_irq(%02X, %02X): IRQ routing for this slot and INT pin combination: %02X\n", card, pci_int, irq_routing); + } + + if (pci_irqs[irq_routing] > 0x0F) + { + pci_log("pci_clear_irq(%02X, %02X): IRQ line is disabled\n", card, pci_int); + return; + } + else + { + irq_line = pci_irqs[irq_routing]; + pci_log("pci_clear_irq(%02X, %02X): Using IRQ %i\n", card, pci_int, irq_line); + } + + if (pci_irq_is_level(irq_line) && !(pci_irq_hold[irq_line] & (1 << card))) + { + /* IRQ not held, do nothing. */ + pci_log("pci_clear_irq(%02X, %02X): Card is not holding the IRQ\n", card, pci_int); + return; + } + + level = pci_irq_is_level(irq_line); + + if (level) + { + pci_log("pci_clear_irq(%02X, %02X): Releasing this card's hold on the IRQ\n", card, pci_int); + pci_irq_hold[irq_line] &= ~(1 << card); + + if (!pci_irq_hold[irq_line]) { - pci_irq_hold[pci_irqs[irq]] &= ~(1 << card); - - /* pclog("Level "); */ - if (!pci_irq_hold[pci_irqs[irq]]) - { - /* pclog("(clearing)\n"); */ - picintc(1 << pci_irqs[irq]); - } - else - { - /* pclog("(held)\n"); */ - } + pci_log("pci_clear_irq(%02X, %02X): IRQ no longer held by any card, clearing it\n", card, pci_int); + picintc(1 << irq_line); } else { - /* pclog("Edge\n"); */ - picintc(1 << pci_irqs[irq]); + pci_log("pci_clear_irq(%02X, %02X): IRQ is still being held\n", card, pci_int); } - } + } + else + { + pci_log("pci_clear_irq(%02X, %02X): Clearing edge-triggered interrupt\n", card, pci_int); + picintc(1 << irq_line); + } } void pci_reset(void) @@ -299,12 +465,39 @@ void pci_reset(void) elcr_reset(); } +static void pci_slots_clear(void) +{ + uint8_t i = 0; + uint8_t j = 0; + + last_pci_card = 0; + + for (i = 0; i < 32; i++) + { + pci_cards[i].id = 0xFF; + pci_cards[i].type = 0xFF; + + for (j = 0; j < 4; j++) + { + pci_cards[i].irq_routing[j] = 0; + } + + pci_cards[i].read = NULL; + pci_cards[i].write = NULL; + pci_cards[i].priv = NULL; + + pci_card_to_slot_mapping[i] = 0xFF; + } +} + void pci_init(int type) { int c; PCI = 1; + pci_slots_clear(); + pci_reset(); io_sethandler(0x04d0, 0x0002, elcr_read, NULL, NULL, elcr_write, NULL, NULL, NULL); @@ -320,46 +513,66 @@ void pci_init(int type) io_sethandler(0x0cfa, 0x0001, pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); } - for (c = 0; c < 32; c++) - { - pci_card_read[c] = NULL; - pci_card_write[c] = NULL; - pci_priv[c] = NULL; - pci_irq_routing[c] = 0; - /* pci_irq_active[c] = 0; */ - pci_card_valid[c] = 0; - } - - for (c = 0; c < 4; c++) - pci_irqs[c] = PCI_IRQ_DISABLED; + for (c = 0; c < 4; c++) + { + pci_irqs[c] = PCI_IRQ_DISABLED; + } } -void pci_slot(int card) +void pci_register_slot(int card, int type, int inta, int intb, int intc, int intd) { - pci_card_valid[card] = 1; + pci_cards[last_pci_card].id = card; + pci_cards[last_pci_card].type = type; + pci_cards[last_pci_card].irq_routing[0] = inta; + pci_cards[last_pci_card].irq_routing[1] = intb; + pci_cards[last_pci_card].irq_routing[2] = intc; + pci_cards[last_pci_card].irq_routing[3] = intd; + pci_cards[last_pci_card].read = NULL; + pci_cards[last_pci_card].write = NULL; + pci_cards[last_pci_card].priv = NULL; + pci_card_to_slot_mapping[card] = last_pci_card; + pci_log("pci_register_slot(): pci_cards[%i].id = %02X\n", last_pci_card, card); + last_pci_card++; } -void pci_add_specific(int card, uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv) +uint8_t pci_add_card(uint8_t add_type, uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv) { - pci_card_read[card] = read; - pci_card_write[card] = write; - pci_priv[card] = priv; -} + uint8_t i = 0; -int pci_add(uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv) -{ - int c; - - for (c = 0; c < 32; c++) - { - if (pci_card_valid[c] && !pci_card_read[c] && !pci_card_write[c]) - { - pci_card_read[c] = read; - pci_card_write[c] = write; - pci_priv[c] = priv; - return c; - } - } - - return -1; + if (add_type < PCI_ADD_NORMAL) + { + pci_log("pci_add_card(): Adding PCI CARD at specific slot %02X [SPECIFIC]\n", add_type); + } + + if (!PCI) + { + pci_log("pci_add_card(): Adding PCI CARD failed (non-PCI machine) [%s]\n", (add_type == PCI_ADD_NORMAL) ? "NORMAL" : ((add_type == PCI_ADD_VIDEO) ? "VIDEO" : "SPECIFIC")); + return 0xFF; + } + + if (!last_pci_card) + { + pci_log("pci_add_card(): Adding PCI CARD failed (no PCI slots) [%s]\n", (add_type == PCI_ADD_NORMAL) ? "NORMAL" : ((add_type == PCI_ADD_VIDEO) ? "VIDEO" : "SPECIFIC")); + return 0xFF; + } + + for (i = 0; i < last_pci_card; i++) + { + if (!pci_cards[i].read && !pci_cards[i].write) + { + if (((pci_cards[i].type == PCI_CARD_NORMAL) && (add_type >= PCI_ADD_NORMAL)) || + ((pci_cards[i].type == PCI_CARD_ONBOARD) && (add_type == PCI_ADD_VIDEO)) || + ((pci_cards[i].id == add_type) && (add_type < PCI_ADD_NORMAL))) + { + pci_cards[i].read = read; + pci_cards[i].write = write; + pci_cards[i].priv = priv; + pci_log("pci_add_card(): Adding PCI CARD to pci_cards[%i] (slot %02X) [%s]\n", i, pci_cards[i].id, (add_type == PCI_ADD_NORMAL) ? "NORMAL" : ((add_type == PCI_ADD_VIDEO) ? "VIDEO" : "SPECIFIC")); + return pci_cards[i].id; + } + } + } + + pci_log("pci_add_card(): Adding PCI CARD failed (unable to find a suitable PCI slot) [%s]\n", (add_type == PCI_ADD_NORMAL) ? "NORMAL" : ((add_type == PCI_ADD_VIDEO) ? "VIDEO" : "SPECIFIC")); + return 0xFF; } diff --git a/src/pci.h b/src/pci.h index 4ef145fd0..f5f1b993e 100644 --- a/src/pci.h +++ b/src/pci.h @@ -1,17 +1,14 @@ -void elcr_reset(void); +void pci_set_irq_routing(int pci_int, int irq); -void pci_init(int type); -void pci_slot(int card); -void pci_add_specific(int card, uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv); -int pci_add(uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv); -void pci_set_irq_routing(int card, int irq); -void pci_set_card_routing(int card, int pci_int); void pci_ide_set_irq(int ide_board, int irq); -void pci_set_irq(int card, int pci_int); +void pci_set_irq(uint8_t card, uint8_t pci_int); void pci_ide_clear_irq(int ide_board, int irq); -void pci_clear_irq(int card, int pci_int); -int pci_irq_is_level(int irq); +void pci_clear_irq(uint8_t card, uint8_t pci_int); + void pci_reset(void); +void pci_init(int type); +void pci_register_slot(int card, int type, int inta, int intb, int intc, int intd); +uint8_t pci_add_card(uint8_t add_type, uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv); #define PCI_REG_COMMAND 0x04 @@ -28,4 +25,20 @@ void pci_reset(void); #define PCI_IRQ_DISABLED -1 +enum +{ + PCI_CARD_NORMAL = 0, + PCI_CARD_ONBOARD, + PCI_CARD_SPECIAL +}; + + +#define PCI_ADD_NORMAL 0x80 +#define PCI_ADD_VIDEO 0x81 + extern int pci_burst_time, pci_nonburst_time; + +typedef union { + uint32_t addr; + uint8_t addr_regs[4]; +} bar_t; diff --git a/src/pci_dummy.c b/src/pci_dummy.c new file mode 100644 index 000000000..128cd187b --- /dev/null +++ b/src/pci_dummy.c @@ -0,0 +1,238 @@ +/* This can also serve as a sample PCI device. */ +#include "ibm.h" +#include "io.h" +#include "pci.h" +#include "pci_dummy.h" + +static uint8_t pci_regs[256]; + +static bar_t pci_bar[2]; + +static uint8_t interrupt_on = 0x00; +static uint8_t card = 0; + +static void pci_dummy_interrupt(int set) +{ + if (set) + { + pci_set_irq(card, pci_regs[0x3D]); + } + else + { + pci_clear_irq(card, pci_regs[0x3D]); + } +} + + +static uint8_t pci_dummy_read(uint16_t Port, void *p) +{ + uint8_t ret = 0; + + switch(Port & 0x20) + { + case 0x00: + return 0x1A; + case 0x01: + return 0x07; + case 0x02: + return 0x0B; + case 0x03: + return 0xAB; + case 0x04: + return pci_regs[0x3C]; + case 0x05: + return pci_regs[0x3D]; + case 0x06: + ret = interrupt_on; + if (interrupt_on) + { + pci_dummy_interrupt(0); + interrupt_on = 0; + } + return ret; + default: + return 0x00; + } +} + +static uint16_t pci_dummy_readw(uint16_t Port, void *p) +{ + return pci_dummy_read(Port, p); +} + + +static uint32_t pci_dummy_readl(uint16_t Port, void *p) +{ + return pci_dummy_read(Port, p); +} + + +static void pci_dummy_write(uint16_t Port, uint8_t Val, void *p) +{ + switch(Port & 0x20) + { + case 0x06: + if (!interrupt_on) + { + interrupt_on = 1; + pci_dummy_interrupt(1); + } + return; + default: + return; + } +} + +static void pci_dummy_writew(uint16_t Port, uint16_t Val, void *p) +{ + pci_dummy_write(Port, Val & 0xFF, p); +} + +static void pci_dummy_writel(uint16_t Port, uint32_t Val, void *p) +{ + pci_dummy_write(Port, Val & 0xFF, p); +} + + +static void pci_dummy_io_remove(void) +{ + io_removehandler(pci_bar[0].addr, 0x0020, pci_dummy_read, pci_dummy_readw, pci_dummy_readl, pci_dummy_write, pci_dummy_writew, pci_dummy_writel, NULL); +} + +static void pci_dummy_io_set(void) +{ + io_sethandler(pci_bar[0].addr, 0x0020, pci_dummy_read, pci_dummy_readw, pci_dummy_readl, pci_dummy_write, pci_dummy_writew, pci_dummy_writel, NULL); +} + + +static uint8_t pci_dummy_pci_read(int func, int addr, void *priv) +{ + pclog("AB0B:071A: PCI_Read(%d, %04x)\n", func, addr); + + switch(addr) { + case 0x00: + return 0x1A; + case 0x01: + return 0x07; + break; + + case 0x02: + return 0x0B; + case 0x03: + return 0xAB; + + case 0x04: /* PCI_COMMAND_LO */ + case 0x05: /* PCI_COMMAND_HI */ + return pci_regs[addr]; + + case 0x06: /* PCI_STATUS_LO */ + case 0x07: /* PCI_STATUS_HI */ + return pci_regs[addr]; + + case 0x08: + case 0x09: + return 0x00; + + case 0x0A: + return pci_regs[addr]; + + case 0x0B: + return pci_regs[addr]; + + case 0x10: /* PCI_BAR 7:5 */ + return (pci_bar[0].addr_regs[0] & 0xe0) | 0x01; + case 0x11: /* PCI_BAR 15:8 */ + return pci_bar[0].addr_regs[1]; + case 0x12: /* PCI_BAR 23:16 */ + return pci_bar[0].addr_regs[2]; + case 0x13: /* PCI_BAR 31:24 */ + return pci_bar[0].addr_regs[3]; + + case 0x2C: + return 0x1A; + case 0x2D: + return 0x07; + + case 0x2E: + return 0x0B; + case 0x2F: + return 0xAB; + + case 0x3C: /* PCI_ILR */ + return pci_regs[addr]; + + case 0x3D: /* PCI_IPR */ + return pci_regs[addr]; + + default: + return 0x00; + } +} + +static void pci_dummy_pci_write(int func, int addr, uint8_t val, void *priv) +{ + uint8_t valxor; + + pclog("AB0B:071A: PCI_Write(%d, %04x, %02x)\n", func, addr, val); + + switch(addr) { + case 0x04: /* PCI_COMMAND_LO */ + valxor = (val & 0x03) ^ pci_regs[addr]; + if (valxor & PCI_COMMAND_IO) + { + pci_dummy_io_remove(); + if (((pci_bar[0].addr & 0xffe0) != 0) && (val & PCI_COMMAND_IO)) + { + pci_dummy_io_set(); + } + } + pci_regs[addr] = val & 0x03; + break; + + case 0x10: /* PCI_BAR */ + val &= 0xe0; /* 0xe0 acc to RTL DS */ + val |= 0x01; /* re-enable IOIN bit */ + /*FALLTHROUGH*/ + + case 0x11: /* PCI_BAR */ + case 0x12: /* PCI_BAR */ + case 0x13: /* PCI_BAR */ + /* Remove old I/O. */ + pci_dummy_io_remove(); + + /* Set new I/O as per PCI request. */ + pci_bar[0].addr_regs[addr & 3] = val; + + /* Then let's calculate the new I/O base. */ + pci_bar[0].addr &= 0xffe0; + + /* Log the new base. */ + pclog("AB0B:071A: PCI: new I/O base is %04X\n", pci_bar[0].addr); + + /* We're done, so get out of the here. */ + if (pci_regs[4] & PCI_COMMAND_IO) + { + if ((pci_bar[0].addr) != 0) + { + pci_dummy_io_set(); + } + } + break; + + case 0x3C: /* PCI_ILR */ + pclog("AB0B:071A: IRQ now: %i\n", val); + pci_regs[addr] = val; + return; + } +} + + +void pci_dummy_init(void) +{ + card = pci_add_card(PCI_ADD_NORMAL, pci_dummy_pci_read, pci_dummy_pci_write, NULL); + + pci_bar[0].addr_regs[0] = 0x01; + pci_regs[0x04] = 0x03; + + pci_regs[0x3D] = PCI_INTD; +} diff --git a/src/pci_dummy.h b/src/pci_dummy.h new file mode 100644 index 000000000..45e1299bc --- /dev/null +++ b/src/pci_dummy.h @@ -0,0 +1 @@ +extern void pci_dummy_init(void); diff --git a/src/piix.c b/src/piix.c index 2456ccf47..92d500685 100644 --- a/src/piix.c +++ b/src/piix.c @@ -683,9 +683,9 @@ void piix3_reset(void) card_piix_ide[0x44] = 0x00; } -void piix_init_common(int card) +void piix_init(int card) { - pci_add_specific(card, piix_read, piix_write, NULL); + pci_add_card(card, piix_read, piix_write, NULL); piix_reset(); @@ -704,30 +704,9 @@ void piix_init_common(int card) pci_reset_handler.pci_set_reset = piix_reset; } -void piix_init(int card, int pci_a, int pci_b, int pci_c, int pci_d) +void piix3_init(int card) { - piix_init_common(card); - - pci_set_card_routing(pci_a, PCI_INTA); - pci_set_card_routing(pci_b, PCI_INTB); - pci_set_card_routing(pci_c, PCI_INTC); - pci_set_card_routing(pci_d, PCI_INTD); -} - -void piix_init_thor(int card, int pci_d_only, int pci_a, int pci_b, int pci_c, int pci_d) -{ - piix_init_common(card); - - pci_set_card_routing(pci_d_only, PCI_INTD); - pci_set_card_routing(pci_a, PCI_INTA); - pci_set_card_routing(pci_b, PCI_INTB); - pci_set_card_routing(pci_c, PCI_INTC); - pci_set_card_routing(pci_d, PCI_INTD); -} - -void piix3_init(int card, int pci_a, int pci_b, int pci_c, int pci_d) -{ - pci_add_specific(card, piix_read, piix_write, NULL); + pci_add_card(card, piix_read, piix_write, NULL); piix3_reset(); @@ -744,9 +723,4 @@ void piix3_init(int card, int pci_a, int pci_b, int pci_c, int pci_d) dma_alias_set(); pci_reset_handler.pci_set_reset = piix3_reset; - - pci_set_card_routing(pci_a, PCI_INTA); - pci_set_card_routing(pci_b, PCI_INTB); - pci_set_card_routing(pci_c, PCI_INTC); - pci_set_card_routing(pci_d, PCI_INTD); } diff --git a/src/piix.h b/src/piix.h index 1073cb110..39dd22317 100644 --- a/src/piix.h +++ b/src/piix.h @@ -16,10 +16,9 @@ * Copyright 2016,2017 Miran Grca. */ -extern void piix_init(int card, int pci_a, int pci_b, int pci_c, int pci_d); -extern void piix_init_thor(int card, int pci_d_only, int pci_a, int pci_b, int pci_c, int pci_d); +extern void piix_init(int card); -extern void piix3_init(int card, int pci_a, int pci_b, int pci_c, int pci_d); +extern void piix3_init(int card); extern uint8_t piix_bus_master_read(uint16_t port, void *priv); extern void piix_bus_master_write(uint16_t port, uint8_t val, void *priv); diff --git a/src/scsi/scsi_buslogic.c b/src/scsi/scsi_buslogic.c index 83bc2e8b8..6126df858 100644 --- a/src/scsi/scsi_buslogic.c +++ b/src/scsi/scsi_buslogic.c @@ -2561,12 +2561,6 @@ BuslogicCommandCallback(void *p) } -typedef union { - uint32_t addr; - uint8_t addr_regs[4]; -} bar_t; - - uint8_t buslogic_pci_regs[256]; bar_t buslogic_pci_bar[3]; @@ -2933,7 +2927,7 @@ BuslogicInit(int chip) &BuslogicCallback, &BuslogicCallback, bl); if (bl->chip == CHIP_BUSLOGIC_PCI) { - bl->Card = pci_add(BuslogicPCIRead, BuslogicPCIWrite, bl); + bl->Card = pci_add_card(PCI_ADD_NORMAL, BuslogicPCIRead, BuslogicPCIWrite, bl); buslogic_pci_bar[0].addr_regs[0] = 1; buslogic_pci_bar[1].addr_regs[0] = 0; diff --git a/src/sio.c b/src/sio.c index 37112936b..fd512fe95 100644 --- a/src/sio.c +++ b/src/sio.c @@ -223,9 +223,9 @@ void sio_reset(void) } -void sio_init(int card, int pci_a, int pci_b, int pci_c, int pci_d) +void sio_init(int card) { - pci_add_specific(card, sio_read, sio_write, NULL); + pci_add_card(card, sio_read, sio_write, NULL); sio_reset(); @@ -238,13 +238,4 @@ void sio_init(int card, int pci_a, int pci_b, int pci_c, int pci_d) dma_alias_set(); pci_reset_handler.pci_set_reset = sio_reset; - - if (pci_a) - pci_set_card_routing(pci_a, PCI_INTA); - if (pci_b) - pci_set_card_routing(pci_b, PCI_INTB); - if (pci_c) - pci_set_card_routing(pci_c, PCI_INTC); - if (pci_d) - pci_set_card_routing(pci_d, PCI_INTD); } diff --git a/src/sio.h b/src/sio.h index bc986dda9..e9d5c26c1 100644 --- a/src/sio.h +++ b/src/sio.h @@ -15,4 +15,4 @@ */ void trc_init(void); -void sio_init(int card, int pci_a, int pci_b, int pci_c, int pci_d); +void sio_init(int card); diff --git a/src/sis496.c b/src/sis496.c index aff1b3eaa..e93776bae 100644 --- a/src/sis496.c +++ b/src/sis496.c @@ -146,15 +146,11 @@ static void sis496_pci_reset(void) void sis496_init(void) { - pci_add_specific(5, sis496_read, sis496_write, NULL); + pci_add_card(5, sis496_read, sis496_write, NULL); sis496_reset(); pci_reset_handler.pci_master_reset = sis496_pci_reset; - - pci_set_card_routing(15, PCI_INTA); - pci_set_card_routing(13, PCI_INTD); - pci_set_card_routing(11, PCI_INTC); } diff --git a/src/video/vid_ati_mach64.c b/src/video/vid_ati_mach64.c index 65ee359b4..824b9a11e 100644 --- a/src/video/vid_ati_mach64.c +++ b/src/video/vid_ati_mach64.c @@ -3315,7 +3315,7 @@ static void *mach64_common_init() mach64_io_set(mach64); - mach64->card = pci_add(mach64_pci_read, mach64_pci_write, mach64); + mach64->card = pci_add_card(PCI_ADD_VIDEO, mach64_pci_read, mach64_pci_write, mach64); mach64->pci_regs[PCI_REG_COMMAND] = 3; mach64->pci_regs[0x30] = 0x00; diff --git a/src/video/vid_et4000w32.c b/src/video/vid_et4000w32.c index ebe6fb483..c01cf1810 100644 --- a/src/video/vid_et4000w32.c +++ b/src/video/vid_et4000w32.c @@ -1161,7 +1161,7 @@ void *et4000w32p_init() et4000w32p_io_set(et4000); - pci_add(et4000w32p_pci_read, et4000w32p_pci_write, et4000); + pci_add_card(PCI_ADD_VIDEO, et4000w32p_pci_read, et4000w32p_pci_write, et4000); /* Hardwired bits: 00000000 1xx0x0xx */ /* R/W bits: xx xxxx */ diff --git a/src/video/vid_nv_riva128.c b/src/video/vid_nv_riva128.c index d43b9e114..0c3005ae7 100644 --- a/src/video/vid_nv_riva128.c +++ b/src/video/vid_nv_riva128.c @@ -2883,7 +2883,7 @@ void rivatnt_pgraph_ctx_switch(void *p) riva128->pgraph.intr = 0; riva128->ptimer.intr = 0; - riva128->pci_card = pci_add(riva128_pci_read, riva128_pci_write, riva128); + riva128->pci_card = pci_add_card(PCI_ADD_VIDEO, riva128_pci_read, riva128_pci_write, riva128); riva128->ptimer.clock_mul = 1; riva128->ptimer.clock_div = 1; @@ -3109,7 +3109,7 @@ device_t riva128_device = riva128->pfifo.intr = 0; riva128->pgraph.intr = 0; - riva128->pci_card = pci_add(riva128_pci_read, rivatnt_pci_write, riva128); + riva128->pci_card = pci_add_card(PCI_ADD_VIDEO, riva128_pci_read, rivatnt_pci_write, riva128); //Some bullshit default values so that the emulator won't shit itself trying to boot. These'll be overwritten by the video BIOS anyway. riva128->pramdac.m_m = 0x03; @@ -3310,7 +3310,7 @@ device_t rivatnt_device = riva128->pfifo.intr = 0; riva128->pgraph.intr = 0; - riva128->pci_card = pci_add(riva128_pci_read, rivatnt_pci_write, riva128); + riva128->pci_card = pci_add_card(PCI_ADD_VIDEO, riva128_pci_read, rivatnt_pci_write, riva128); //Some bullshit default values so that the emulator won't shit itself trying to boot. These'll be overwritten by the video BIOS anyway. riva128->pramdac.m_m = 0x03; diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index b587f6630..ecb7937b5 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -2179,8 +2179,8 @@ static void *s3_init(wchar_t *bios_fn, int chip) s3_io_set(s3); - s3->card = pci_add(s3_pci_read, s3_pci_write, s3); - + s3->card = pci_add_card(PCI_ADD_VIDEO, s3_pci_read, s3_pci_write, s3); + s3->pci_regs[0x04] = 7; s3->pci_regs[0x30] = 0x00; diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index c61a672ca..0b66093e3 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -3828,7 +3828,7 @@ static void *s3_virge_init() virge->is_375 = 0; - virge->card = pci_add(s3_virge_pci_read, s3_virge_pci_write, virge); + virge->card = pci_add_card(PCI_ADD_VIDEO, s3_virge_pci_read, s3_virge_pci_write, virge); virge->wake_render_thread = thread_create_event(); virge->wake_main_thread = thread_create_event(); @@ -3922,7 +3922,7 @@ static void *s3_virge_988_init() virge->is_375 = 0; - virge->card = pci_add(s3_virge_pci_read, s3_virge_pci_write, virge); + virge->card = pci_add_card(PCI_ADD_VIDEO, s3_virge_pci_read, s3_virge_pci_write, virge); virge->wake_render_thread = thread_create_event(); virge->wake_main_thread = thread_create_event(); @@ -4017,7 +4017,7 @@ static void *s3_virge_375_init(wchar_t *romfn) virge->is_375 = 1; - virge->card = pci_add(s3_virge_pci_read, s3_virge_pci_write, virge); + virge->card = pci_add_card(PCI_ADD_VIDEO, s3_virge_pci_read, s3_virge_pci_write, virge); virge->wake_render_thread = thread_create_event(); virge->wake_main_thread = thread_create_event(); diff --git a/src/video/vid_tgui9440.c b/src/video/vid_tgui9440.c index bcd4a7c95..e13b76fa9 100644 --- a/src/video/vid_tgui9440.c +++ b/src/video/vid_tgui9440.c @@ -526,7 +526,7 @@ void *tgui9440_init() io_sethandler(0x03c0, 0x0020, tgui_in, NULL, NULL, tgui_out, NULL, NULL, tgui); io_sethandler(0x43c8, 0x0002, tgui_in, NULL, NULL, tgui_out, NULL, NULL, tgui); - pci_add(tgui_pci_read, tgui_pci_write, tgui); + pci_add_card(PCI_ADD_VIDEO, tgui_pci_read, tgui_pci_write, tgui); tgui->wake_fifo_thread = thread_create_event(); tgui->fifo_not_full_event = thread_create_event(); diff --git a/src/video/vid_voodoo.c b/src/video/vid_voodoo.c index 02219ef1c..91ae9ef3d 100644 --- a/src/video/vid_voodoo.c +++ b/src/video/vid_voodoo.c @@ -7492,7 +7492,7 @@ void *voodoo_card_init() else voodoo_generate_filter_v1(voodoo); - pci_add(voodoo_pci_read, voodoo_pci_write, voodoo); + pci_add_card(PCI_ADD_NORMAL, voodoo_pci_read, voodoo_pci_write, voodoo); mem_mapping_add(&voodoo->mapping, 0, 0, NULL, voodoo_readw, voodoo_readl, NULL, voodoo_writew, voodoo_writel, NULL, MEM_MAPPING_EXTERNAL, voodoo);