From c6359517c160ec11d4177b47cebec8cf5c22ae4f Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 11 Feb 2023 22:15:50 +0100 Subject: [PATCH] More pci_dummy.c fixes and it's now instantiable and the exposed init function initializes it for PCI slot brute force purposes. --- src/include/86box/pci_dummy.h | 2 +- src/pci_dummy.c | 243 ++++++++++++++++++++-------------- 2 files changed, 147 insertions(+), 98 deletions(-) diff --git a/src/include/86box/pci_dummy.h b/src/include/86box/pci_dummy.h index d221ddd2e..104437b6e 100644 --- a/src/include/86box/pci_dummy.h +++ b/src/include/86box/pci_dummy.h @@ -1,6 +1,6 @@ #ifndef EMU_PCI_DUMMY_H #define EMU_PCI_DUMMY_H -extern void pci_dummy_init(void); +extern void pci_dummy_init(int min_slot, int max_slot, int nb_slot, int sb_slot); #endif /*EMU_PCI_DUMMY_H*/ diff --git a/src/pci_dummy.c b/src/pci_dummy.c index 03141fa2c..a54b63260 100644 --- a/src/pci_dummy.c +++ b/src/pci_dummy.c @@ -1,57 +1,68 @@ /* This can also serve as a sample PCI device. */ #include #include +#include #include #include #include <86box/86box.h> +#include <86box/device.h> #include <86box/io.h> #include <86box/pci.h> #include <86box/pci_dummy.h> -static uint8_t pci_regs[256]; +typedef struct +{ + uint8_t pci_regs[256]; -static bar_t pci_bar[2]; + bar_t pci_bar[2]; -static uint8_t interrupt_on = 0x00; -static uint8_t card = 0; + uint8_t card, interrupt_on; +} pci_dummy_t; static void -pci_dummy_interrupt(int set) +pci_dummy_interrupt(int set, pci_dummy_t *dev) { if (set) - pci_set_irq(card, pci_regs[0x3D]); + pci_set_irq(dev->card, dev->pci_regs[0x3D]); else - pci_clear_irq(card, pci_regs[0x3D]); + pci_clear_irq(dev->card, dev->pci_regs[0x3D]); } static uint8_t pci_dummy_read(uint16_t Port, void *p) { - uint8_t ret = 0; + pci_dummy_t *dev = (pci_dummy_t *) p; + uint8_t ret = 0xff; switch (Port & 0x20) { case 0x00: - return 0x1A; + ret = 0x1a; + break; case 0x01: - return 0x07; + ret = 0x07; + break; case 0x02: - return 0x0B; + ret = 0x0b; + break; case 0x03: - return 0xAB; + ret = 0xab; + break; case 0x04: - return pci_regs[0x3C]; + ret = dev->pci_regs[0x3c]; + break; case 0x05: - return pci_regs[0x3D]; + ret = dev->pci_regs[0x3d]; + break; case 0x06: - ret = interrupt_on; - if (interrupt_on) { - pci_dummy_interrupt(0); - interrupt_on = 0; + ret = dev->interrupt_on; + if (dev->interrupt_on) { + pci_dummy_interrupt(0, dev); + dev->interrupt_on = 0; } - return ret; - default: - return 0x00; + break; } + + return ret; } static uint16_t @@ -69,11 +80,13 @@ pci_dummy_readl(uint16_t Port, void *p) static void pci_dummy_write(uint16_t Port, uint8_t Val, void *p) { + pci_dummy_t *dev = (pci_dummy_t *) p; + switch (Port & 0x20) { case 0x06: - if (!interrupt_on) { - interrupt_on = 1; - pci_dummy_interrupt(1); + if (!dev->interrupt_on) { + dev->interrupt_on = 1; + pci_dummy_interrupt(1, dev); } return; default: @@ -94,143 +107,179 @@ pci_dummy_writel(uint16_t Port, uint32_t Val, void *p) } static void -pci_dummy_io_remove(void) +pci_dummy_io_remove(pci_dummy_t *dev) { - 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); + io_removehandler(dev->pci_bar[0].addr, 0x0020, pci_dummy_read, pci_dummy_readw, pci_dummy_readl, pci_dummy_write, pci_dummy_writew, pci_dummy_writel, dev); } static void -pci_dummy_io_set(void) +pci_dummy_io_set(pci_dummy_t *dev) { - 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); + io_sethandler(dev->pci_bar[0].addr, 0x0020, pci_dummy_read, pci_dummy_readw, pci_dummy_readl, pci_dummy_write, pci_dummy_writew, pci_dummy_writel, dev); } static uint8_t pci_dummy_pci_read(int func, int addr, void *priv) { - pclog("AB0B:071A: PCI_Read(%d, %04x)\n", func, addr); + pci_dummy_t *dev = (pci_dummy_t *) priv; + uint8_t ret = 0xff; if (func == 0x00) switch (addr) { - case 0x00: - return 0x1A; - case 0x01: - return 0x07; + case 0x00: case 0x2c: + ret = 0x1a; + break; + case 0x01: case 0x2d: + ret = 0x07; break; - case 0x02: - return 0x0B; - case 0x03: - return 0xAB; + case 0x02: case 0x2e: + ret = 0x0b; + break; + case 0x03: case 0x2f: + ret = 0xab; + break; 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 0x0a: case 0x0b: + case 0x3c: /* PCI_ILR */ + ret = dev->pci_regs[addr]; + break; - case 0x08: - case 0x09: - return 0x00; - - case 0x0A: - return pci_regs[addr]; - - case 0x0B: - return pci_regs[addr]; + case 0x08: /* Techncially, revision, but we return the card (slot) here. */ + ret = dev->card; + break; case 0x10: /* PCI_BAR 7:5 */ - return (pci_bar[0].addr_regs[0] & 0xe0) | 0x01; + ret = (dev->pci_bar[0].addr_regs[0] & 0xe0) | 0x01; + break; 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]; + ret = dev->pci_bar[0].addr_regs[1]; + break; - 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]; + case 0x3d: /* PCI_IPR */ + ret = PCI_INTA; + break; default: - return 0x00; - } else - return 0xff; + ret = 0x00; + break; + } + + pclog("AB0B:071A: PCI_Read(%d, %04X) = %02X\n", func, addr, ret); + + return ret; } static void pci_dummy_pci_write(int func, int addr, uint8_t val, void *priv) { + pci_dummy_t *dev = (pci_dummy_t *) priv; uint8_t valxor; pclog("AB0B:071A: PCI_Write(%d, %04x, %02x)\n", func, addr, val); if (func == 0x00) switch (addr) { case 0x04: /* PCI_COMMAND_LO */ - valxor = (val & 0x03) ^ pci_regs[addr]; + valxor = (val & 0x03) ^ dev->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_dummy_io_remove(dev); + if ((dev->pci_bar[0].addr != 0) && (val & PCI_COMMAND_IO)) + pci_dummy_io_set(dev); } - pci_regs[addr] = val & 0x03; + dev->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(); + pci_dummy_io_remove(dev); /* Set new I/O as per PCI request. */ - pci_bar[0].addr_regs[addr & 3] = val; + dev->pci_bar[0].addr_regs[addr & 3] = val; /* Then let's calculate the new I/O base. */ - pci_bar[0].addr &= 0xffe0; + dev->pci_bar[0].addr &= 0xffe0; /* Log the new base. */ - pclog("AB0B:071A: PCI: new I/O base is %04X\n", pci_bar[0].addr); + pclog("AB0B:071A: PCI: new I/O base is %04X\n", dev->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(); + if (dev->pci_regs[4] & PCI_COMMAND_IO) { + if ((dev->pci_bar[0].addr) != 0) + pci_dummy_io_set(dev); } break; - case 0x3C: /* PCI_ILR */ + case 0x3c: /* PCI_ILR */ pclog("AB0B:071A: IRQ now: %i\n", val); - pci_regs[addr] = val; + dev->pci_regs[addr] = val; return; } } -void -pci_dummy_init(void) +static void +pci_dummy_reset(void *priv) { - card = pci_add_card(PCI_ADD_NORMAL, pci_dummy_pci_read, pci_dummy_pci_write, NULL); + pci_dummy_t *dev = (pci_dummy_t *) priv; - pci_bar[0].addr_regs[0] = 0x01; - pci_regs[0x04] = 0x03; + /* Lower the IRQ. */ + pci_dummy_interrupt(0, dev); - pci_regs[0x3D] = PCI_INTA; + /* Disable I/O and memory accesses. */ + pci_dummy_pci_write(0x00, 0x04, 0x00, dev); + + /* Zero all the registers. */ + memset(dev, 0x00, sizeof(pci_dummy_t)); +} + +static void +pci_dummy_close(void *priv) +{ + pci_dummy_t *dev = (pci_dummy_t *) priv; + + free(dev); +} + +static void * +pci_dummy_card_init(const device_t *info) +{ + pci_dummy_t *dev = (pci_dummy_t *) calloc(1, sizeof(pci_dummy_t)); + + dev->card = pci_add_card(PCI_ADD_NORMAL, pci_dummy_pci_read, pci_dummy_pci_write, dev); + + return dev; +} + +const device_t pci_dummy_device = { + .name = "Dummy Device (PCI)", + .internal_name = "pci_dummy", + .flags = DEVICE_PCI, + .local = 0, + .init = pci_dummy_card_init, + .close = pci_dummy_close, + .reset = pci_dummy_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +void +pci_dummy_init(int min_slot, int max_slot, int nb_slot, int sb_slot) +{ + int i = 0, j = 1; + + for (i = min_slot; i <= max_slot; i++) { + if ((i != nb_slot) && (i != sb_slot)) { + pci_register_slot(j, PCI_CARD_NORMAL, 1, 3, 2, 4); + device_add_inst(&pci_dummy_device, j); + j++; + } + } }