From e04ebd69a2df1567402cdbe7fba86bdf8a75ec74 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 6 Apr 2021 07:30:11 +0200 Subject: [PATCH] PCI changes. --- src/include/86box/pci.h | 1 + src/pci.c | 72 +++++++++++++++++++++++++++-------------- 2 files changed, 49 insertions(+), 24 deletions(-) diff --git a/src/include/86box/pci.h b/src/include/86box/pci.h index e01deb371..e59268742 100644 --- a/src/include/86box/pci.h +++ b/src/include/86box/pci.h @@ -104,6 +104,7 @@ extern uint8_t pci_get_int(uint8_t card, uint8_t pci_int); extern void pci_reset(void); extern void pci_init(int type); extern uint8_t pci_register_bus(); +extern void pci_set_pmc(uint8_t pmc); extern void pci_remap_bus(uint8_t bus_index, uint8_t bus_number); extern void pci_register_slot(int card, int type, int inta, int intb, int intc, int intd); diff --git a/src/pci.c b/src/pci.c index 22ec1dc26..2283ca60d 100644 --- a/src/pci.c +++ b/src/pci.c @@ -188,6 +188,35 @@ 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_set_pmc(uint8_t pmc) +{ + pci_reset_regs(); + + if (!pci_pmc && (pmc & 0x01)) { + 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(0x0cfc, 4, + pci_read,NULL,NULL, pci_write,NULL,NULL, NULL); + } else if (pci_pmc && !(pmc & 0x01)) { + 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); + io_sethandler(0x0cf8, 1, + pci_type2_read,NULL,NULL, pci_type2_write,NULL,NULL, NULL); + io_sethandler(0x0cfa, 1, + pci_type2_read,NULL,NULL, pci_type2_write,NULL,NULL, NULL); + } + + pci_pmc = (pmc & 0x01); +} + + static void pci_type2_write(uint16_t port, uint8_t val, void *priv) { @@ -209,29 +238,8 @@ pci_type2_write(uint16_t port, uint8_t val, void *priv) } else if (port == 0xcfa) pci_bus = val; else if (port == 0xcfb) { - pci_reset_regs(); - - if (!pci_pmc && (val & 0x01)) { - 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(0x0cfc, 4, - pci_read,NULL,NULL, pci_write,NULL,NULL, NULL); - } else if (pci_pmc && !(val & 0x01)) { - 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); - io_sethandler(0x0cf8, 1, - pci_type2_read,NULL,NULL, pci_type2_write,NULL,NULL, NULL); - io_sethandler(0x0cfa, 1, - pci_type2_read,NULL,NULL, pci_type2_write,NULL,NULL, NULL); - } - - pci_pmc = (val & 0x01); + pci_log("Write %02X to port 0CFB\n", val); + pci_set_pmc(val); } else { pci_card = (port >> 8) & 0xf; pci_index = port & 0xff; @@ -253,6 +261,20 @@ pci_type2_write(uint16_t port, uint8_t val, void *priv) } +static void +pci_type2_writel(uint16_t port, uint32_t val, void *priv) +{ + int i; + + for (i = 0; i < 4; i++) { + /* Make sure to have the DWORD write not pass through to PMC if mechanism 1 is in use, + as otherwise, the PCI enable bits clobber it. */ + if (!pci_pmc || ((port + i) != 0x0cfb)) + pci_type2_write(port + i, val >> 8, priv); + } +} + + static uint8_t pci_type2_read(uint16_t port, void *priv) { @@ -761,7 +783,7 @@ pci_init(int type) pci_pmc = 0x00; io_sethandler(0x0cfb, 1, - pci_type2_read,NULL,NULL, pci_type2_write,NULL,NULL, NULL); + pci_type2_read,NULL,NULL, pci_type2_write,NULL,pci_type2_writel, NULL); } if (type & PCI_NO_IRQ_STEERING) { @@ -777,11 +799,13 @@ pci_init(int type) NULL,NULL,pci_cf8_read, NULL,NULL,pci_cf8_write, NULL); io_sethandler(0x0cfc, 4, pci_read,NULL,NULL, pci_write,NULL,NULL, NULL); + pci_pmc = 1; } else { io_sethandler(0x0cf8, 1, pci_type2_read,NULL,NULL, pci_type2_write,NULL,NULL, NULL); io_sethandler(0x0cfa, 1, pci_type2_read,NULL,NULL, pci_type2_write,NULL,NULL, NULL); + pci_pmc = 0; } for (c = 0; c < 4; c++) {