diff --git a/src/include/86box/pci.h b/src/include/86box/pci.h index 230af8993..9f36fd7c9 100644 --- a/src/include/86box/pci.h +++ b/src/include/86box/pci.h @@ -27,9 +27,10 @@ #define PCI_COMMAND_IO 0x01 #define PCI_COMMAND_MEM 0x02 -#define PCI_NO_IRQ_STEERING 0x8000 -#define PCI_CAN_SWITCH_TYPE 0x10000 -#define PCI_NO_BRIDGES 0x20000 +#define PCI_NO_IRQ_STEERING 0x8000 +#define PCI_CAN_SWITCH_TYPE 0x10000 +#define PCI_NO_BRIDGES 0x20000 +#define PCI_ALWAYS_EXPOSE_DEV0 0x40000 #define PCI_CONFIG_TYPE_1 1 #define PCI_CONFIG_TYPE_2 2 diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 638ac831b..0a4e7c21f 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -632,7 +632,10 @@ machine_at_pc330_6573_init(const machine_t *model) /* doesn't like every CPU oth return ret; machine_at_common_init(model); + + pci_init(PCI_CAN_SWITCH_TYPE | PCI_ALWAYS_EXPOSE_DEV0); pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 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); diff --git a/src/machine/m_at_socket4.c b/src/machine/m_at_socket4.c index b67277ed7..7c9ccaf42 100644 --- a/src/machine/m_at_socket4.c +++ b/src/machine/m_at_socket4.c @@ -385,11 +385,14 @@ machine_at_p5vl_init(const machine_t *model) return ret; machine_at_common_init(model); - pci_init(PCI_CONFIG_TYPE_1); + + pci_init(PCI_CAN_SWITCH_TYPE | PCI_ALWAYS_EXPOSE_DEV0); pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 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); + device_add(&opti5x7_pci_device); device_add(&opti822_device); device_add(&sst_flash_29ee010_device); diff --git a/src/machine/m_at_socket5.c b/src/machine/m_at_socket5.c index 94d1b5ea6..3a0adbe50 100644 --- a/src/machine/m_at_socket5.c +++ b/src/machine/m_at_socket5.c @@ -335,11 +335,14 @@ machine_at_hot543_init(const machine_t *model) return ret; machine_at_common_init(model); - pci_init(PCI_CONFIG_TYPE_1); + + pci_init(PCI_CAN_SWITCH_TYPE | PCI_ALWAYS_EXPOSE_DEV0); pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 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); + device_add(&opti5x7_pci_device); device_add(&opti822_device); device_add(&sst_flash_29ee010_device); diff --git a/src/pci.c b/src/pci.c index b4078167c..a872d4e00 100644 --- a/src/pci.c +++ b/src/pci.c @@ -59,14 +59,15 @@ static uint8_t pci_irqs[16], pci_irq_level[16]; static uint64_t pci_irq_hold[16]; static pci_mirq_t pci_mirqs[8]; static int pci_type, - pci_switch, - pci_index, - pci_func, - pci_card, - pci_bus, - pci_enable, - pci_key; -static int trc_reg = 0; + pci_switch, + pci_index, + pci_func, + pci_card, + pci_bus, + pci_enable, + pci_key; +static int trc_reg = 0; +static uint32_t pci_base = 0xc000, pci_size = 0x1000; static void pci_reset_regs(void); @@ -388,22 +389,39 @@ static uint8_t pci_type2_read(uint16_t port, void *priv); void pci_set_pmc(uint8_t pmc) { - pci_reset_regs(); + // pci_reset_regs(); if (!pci_pmc && (pmc & 0x01)) { + io_removehandler(pci_base, pci_size, + pci_type2_read, NULL, NULL, + pci_type2_write, NULL, NULL, NULL); + io_removehandler(0x0cf8, 1, pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); io_removehandler(0x0cfa, 1, pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); io_sethandler(0x0cf8, 1, NULL, NULL, pci_cf8_read, NULL, NULL, pci_cf8_write, NULL); + io_sethandler(0x0cfa, 1, + pci_type2_read,NULL,NULL, pci_type2_write,NULL,NULL, NULL); io_sethandler(0x0cfc, 4, - pci_read, NULL, NULL, pci_write, NULL, NULL, NULL); + pci_read,pci_readw,pci_readl, pci_write,pci_writew,pci_writel, NULL); } else if (pci_pmc && !(pmc & 0x01)) { + io_removehandler(pci_base, pci_size, + pci_type2_read, NULL, NULL, + pci_type2_write, NULL, NULL, NULL); + if (pci_key) { + io_sethandler(pci_base, pci_size, + pci_type2_read, NULL, NULL, + pci_type2_write, NULL, NULL, NULL); + } + io_removehandler(0x0cf8, 1, NULL, NULL, pci_cf8_read, NULL, NULL, pci_cf8_write, NULL); + io_removehandler(0x0cfa, 1, + pci_type2_read,NULL,NULL, pci_type2_write,NULL,NULL, NULL); io_removehandler(0x0cfc, 4, - pci_read, NULL, NULL, pci_write, NULL, NULL, NULL); + pci_read,pci_readw,pci_readl, pci_write,pci_writew,pci_writel, NULL); io_sethandler(0x0cf8, 1, pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); io_sethandler(0x0cfa, 1, @@ -421,19 +439,36 @@ pci_type2_write(uint16_t port, uint8_t val, void *priv) if (port == 0xcf8) { pci_func = (val >> 1) & 7; - if (!pci_key && (val & 0xf0)) - io_sethandler(0xc000, 0x1000, + if (!pci_key && (val & 0xf0)) { + io_removehandler(pci_base, pci_size, + pci_type2_read, NULL, NULL, + pci_type2_write, NULL, NULL, NULL); + io_sethandler(pci_base, pci_size, pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); - else if (pci_key && !(val & 0xf0)) - io_removehandler(0xc000, 0x1000, + } else if (pci_key && !(val & 0xf0)) + io_removehandler(pci_base, pci_size, pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); pci_key = val & 0xf0; - } else if (port == 0xcfa) + } else if (port == 0xcfa) { pci_bus = val; - else if (port == 0xcfb) { + + pci_log("Allocating ports %04X-%04X...\n", pci_base, pci_base + pci_size - 1); + + /* Evidently, writing here, we should also enable the + configuration space. */ + io_removehandler(pci_base, pci_size, + pci_type2_read, NULL, NULL, + pci_type2_write, NULL, NULL, NULL); + io_sethandler(pci_base, pci_size, + pci_type2_read, NULL, NULL, + pci_type2_write, NULL, NULL, NULL); + + /* Mark as enabled. */ + pci_key |= 0x100; + } else if (port == 0xcfb) { pci_log("Write %02X to port 0CFB\n", val); pci_set_pmc(val); } else { @@ -473,32 +508,36 @@ static uint8_t pci_type2_read(uint16_t port, void *priv) { uint8_t slot = 0; + uint8_t ret = 0xff; if (port == 0xcf8) - return pci_key | (pci_func << 1); + ret = pci_key | (pci_func << 1); else if (port == 0xcfa) - return pci_bus; + ret = pci_bus; else if (port == 0xcfb) - return pci_pmc; + ret = pci_pmc; + else { + pci_card = (port >> 8) & 0xf; + pci_index = port & 0xff; - pci_card = (port >> 8) & 0xf; - pci_index = port & 0xff; - - slot = pci_card_to_slot_mapping[pci_bus_number_to_index_mapping[pci_bus]][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); + slot = pci_card_to_slot_mapping[pci_bus_number_to_index_mapping[pci_bus]][pci_card]; + if (slot != 0xff) { + if (pci_cards[slot].read) + ret = pci_cards[slot].read(pci_func, pci_index | (port & 3), pci_cards[slot].priv); +#ifdef ENABLE_PCI_LOG + else + pci_log("Reading from empty PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index); +#endif + } #ifdef ENABLE_PCI_LOG else - pci_log("Reading from empty PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index); -#endif - } -#ifdef ENABLE_PCI_LOG - else - pci_log("Reading from unasisgned PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index); + pci_log("Reading from unasisgned PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index); #endif - return 0xff; + pci_log("Reading %02X at PCI register %02X at bus %02X, card %02X, function %02X\n", ret, pci_index, pci_bus, pci_card, pci_func); + } + + return ret; } void @@ -782,7 +821,7 @@ pci_reset_regs(void) { pci_index = pci_card = pci_func = pci_bus = pci_key = 0; - io_removehandler(0xc000, 0x1000, + io_removehandler(pci_base, pci_size, pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); } @@ -821,7 +860,11 @@ pci_reset(void) io_removehandler(0x0cf8, 1, NULL, NULL, pci_cf8_read, NULL, NULL, pci_cf8_write, NULL); io_removehandler(0x0cfc, 4, - pci_read, NULL, NULL, pci_write, NULL, NULL, NULL); + pci_read,pci_readw,pci_readl, pci_write,pci_writew,pci_writel, NULL); + io_removehandler(0x0cf8, 1, + pci_type2_read,NULL,NULL, pci_type2_write,NULL,NULL, NULL); + io_removehandler(0x0cfa, 1, + pci_type2_read,NULL,NULL, pci_type2_write,NULL,NULL, NULL); io_sethandler(0x0cf8, 1, pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); io_sethandler(0x0cfa, 1, @@ -931,6 +974,9 @@ pci_init(int type) { int c; + pci_base = 0xc000; + pci_size = 0x1000; + pci_slots_clear(); pci_reset_hard(); @@ -967,6 +1013,15 @@ pci_init(int type) io_sethandler(0x0cfa, 1, pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); pci_pmc = 0; + + if (type & PCI_ALWAYS_EXPOSE_DEV0) { + pci_base = 0xc100; + pci_size = 0x0f00; + + io_sethandler(0xc000, 0x0100, + pci_type2_read, NULL, NULL, + pci_type2_write, NULL, NULL, NULL); + } } for (c = 0; c < 4; c++) {