From 04bea78e5edf10009265d173eced91866d8b9a0e Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Tue, 19 Oct 2021 00:17:27 -0300 Subject: [PATCH] PIIX: Implement drive separation on IDE I/O traps --- src/chipset/intel_piix.c | 117 ++++++++++++++++++++++----------------- src/chipset/via_pipc.c | 2 +- 2 files changed, 66 insertions(+), 53 deletions(-) diff --git a/src/chipset/intel_piix.c b/src/chipset/intel_piix.c index aeed83ab5..095dd5d36 100644 --- a/src/chipset/intel_piix.c +++ b/src/chipset/intel_piix.c @@ -41,6 +41,8 @@ #include <86box/pic.h> #include <86box/pit.h> #include <86box/port_92.h> +#include <86box/scsi_device.h> +#include <86box/hdc.h> #include <86box/hdc_ide.h> #include <86box/hdc_ide_sff8038i.h> #include <86box/usb.h> @@ -284,6 +286,17 @@ piix_trap_io(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv) } +static void +piix_trap_io_ide(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv) +{ + piix_io_trap_t *trap = (piix_io_trap_t *) priv; + + /* IDE traps are per drive, not per channel. */ + if (ide_drives[trap->dev_id]->selected) + piix_trap_io(size, addr, write, val, priv); +} + + static void piix_trap_update_devctl(piix_t *dev, uint8_t trap_id, uint8_t dev_id, uint32_t devctl_mask, uint8_t enable, @@ -294,8 +307,8 @@ piix_trap_update_devctl(piix_t *dev, uint8_t trap_id, uint8_t dev_id, /* Set up Device I/O traps dynamically. */ if (enable && !trap->trap) { - trap->dev = dev; - trap->trap = io_trap_add(piix_trap_io, trap); + trap->dev = dev; + trap->trap = io_trap_add((dev_id <= 3) ? piix_trap_io_ide : piix_trap_io, trap); trap->dev_id = dev_id; trap->sts_reg = &dev->acpi->regs.devsts; trap->sts_mask = 0x00010000 << dev_id; @@ -348,49 +361,49 @@ piix_trap_update(void *priv) piix_trap_update_devctl(dev, trap_id++, 5, 0x00000800, fregs[0x51] & 0x10, 0x377 + (0x80 * !(fregs[0x63] & 0x10)), 1); switch (fregs[0x67] & 0x07) { - case 0x00: temp = 0x3f8; break; - case 0x01: temp = 0x2f8; break; - case 0x02: temp = 0x220; break; - case 0x03: temp = 0x228; break; - case 0x04: temp = 0x238; break; - case 0x05: temp = 0x2e8; break; - case 0x06: temp = 0x338; break; - default: temp = 0x3e8; break; + case 0x00: temp = 0x3f8; break; + case 0x01: temp = 0x2f8; break; + case 0x02: temp = 0x220; break; + case 0x03: temp = 0x228; break; + case 0x04: temp = 0x238; break; + case 0x05: temp = 0x2e8; break; + case 0x06: temp = 0x338; break; + default: temp = 0x3e8; break; } piix_trap_update_devctl(dev, trap_id++, 6, 0x00002000, fregs[0x51] & 0x40, temp, 8); switch (fregs[0x67] & 0x70) { - case 0x00: temp = 0x3f8; break; - case 0x10: temp = 0x2f8; break; - case 0x20: temp = 0x220; break; - case 0x30: temp = 0x228; break; - case 0x40: temp = 0x238; break; - case 0x50: temp = 0x2e8; break; - case 0x60: temp = 0x338; break; - default: temp = 0x3e8; break; + case 0x00: temp = 0x3f8; break; + case 0x10: temp = 0x2f8; break; + case 0x20: temp = 0x220; break; + case 0x30: temp = 0x228; break; + case 0x40: temp = 0x238; break; + case 0x50: temp = 0x2e8; break; + case 0x60: temp = 0x338; break; + default: temp = 0x3e8; break; } piix_trap_update_devctl(dev, trap_id++, 7, 0x00008000, fregs[0x52] & 0x01, temp, 8); switch (fregs[0x63] & 0x06) { - case 0x00: - piix_trap_update_devctl(dev, trap_id++, 8, 0x00020000, fregs[0x52] & 0x04, 0x3bc, 4); - piix_trap_update_devctl(dev, trap_id++, 8, 0x00020000, fregs[0x52] & 0x04, 0x7bc, 3); - break; + case 0x00: + piix_trap_update_devctl(dev, trap_id++, 8, 0x00020000, fregs[0x52] & 0x04, 0x3bc, 4); + piix_trap_update_devctl(dev, trap_id++, 8, 0x00020000, fregs[0x52] & 0x04, 0x7bc, 3); + break; - case 0x02: - piix_trap_update_devctl(dev, trap_id++, 8, 0x00020000, fregs[0x52] & 0x04, 0x378, 8); - piix_trap_update_devctl(dev, trap_id++, 8, 0x00020000, fregs[0x52] & 0x04, 0x778, 3); - break; + case 0x02: + piix_trap_update_devctl(dev, trap_id++, 8, 0x00020000, fregs[0x52] & 0x04, 0x378, 8); + piix_trap_update_devctl(dev, trap_id++, 8, 0x00020000, fregs[0x52] & 0x04, 0x778, 3); + break; - case 0x04: - piix_trap_update_devctl(dev, trap_id++, 8, 0x00020000, fregs[0x52] & 0x04, 0x278, 8); - piix_trap_update_devctl(dev, trap_id++, 8, 0x00020000, fregs[0x52] & 0x04, 0x678, 3); - break; + case 0x04: + piix_trap_update_devctl(dev, trap_id++, 8, 0x00020000, fregs[0x52] & 0x04, 0x278, 8); + piix_trap_update_devctl(dev, trap_id++, 8, 0x00020000, fregs[0x52] & 0x04, 0x678, 3); + break; - default: - piix_trap_update_devctl(dev, trap_id++, 8, 0x00020000, fregs[0x52] & 0x04, 0, 0); - piix_trap_update_devctl(dev, trap_id++, 8, 0x00020000, fregs[0x52] & 0x04, 0, 0); - break; + default: + piix_trap_update_devctl(dev, trap_id++, 8, 0x00020000, fregs[0x52] & 0x04, 0, 0); + piix_trap_update_devctl(dev, trap_id++, 8, 0x00020000, fregs[0x52] & 0x04, 0, 0); + break; } temp = fregs[0x62] & 0x0f; @@ -1059,7 +1072,7 @@ piix_read(int func, int addr, void *priv) /* Return on unsupported function. */ if ((func <= dev->max_func) || ((func == 1) && (dev->max_func == 0))) { - fregs = (uint8_t *) dev->regs[func]; + fregs = (uint8_t *) dev->regs[func]; ret = fregs[addr]; if ((func == 0) && (addr == 0x4e)) ret |= keyboard_at_get_mouse_scan(); @@ -1147,21 +1160,21 @@ piix_reset_hard(piix_t *dev) /* Clear all 4 functions' arrays and set their vendor and device ID's. */ for (i = 0; i < 4; i++) { - memset(dev->regs[i], 0, 256); - if (dev->type == 5) { - dev->regs[i][0x00] = 0x55; dev->regs[i][0x01] = 0x10; /* SMSC/EFAR */ - if (i == 1) { /* IDE controller is 9130, breaking convention */ - dev->regs[i][0x02] = 0x30; - dev->regs[i][0x03] = 0x91; - } else { - dev->regs[i][0x02] = (dev->func0_id & 0xff) + (i << dev->func_shift); - dev->regs[i][0x03] = (dev->func0_id >> 8); - } - } else { - dev->regs[i][0x00] = 0x86; dev->regs[i][0x01] = 0x80; /* Intel */ - dev->regs[i][0x02] = (dev->func0_id & 0xff) + (i << dev->func_shift); - dev->regs[i][0x03] = (dev->func0_id >> 8); - } + memset(dev->regs[i], 0, 256); + if (dev->type == 5) { + dev->regs[i][0x00] = 0x55; dev->regs[i][0x01] = 0x10; /* SMSC/EFAR */ + if (i == 1) { /* IDE controller is 9130, breaking convention */ + dev->regs[i][0x02] = 0x30; + dev->regs[i][0x03] = 0x91; + } else { + dev->regs[i][0x02] = (dev->func0_id & 0xff) + (i << dev->func_shift); + dev->regs[i][0x03] = (dev->func0_id >> 8); + } + } else { + dev->regs[i][0x00] = 0x86; dev->regs[i][0x01] = 0x80; /* Intel */ + dev->regs[i][0x02] = (dev->func0_id & 0xff) + (i << dev->func_shift); + dev->regs[i][0x03] = (dev->func0_id >> 8); + } } /* Function 0: PCI to ISA Bridge */ @@ -1172,7 +1185,7 @@ piix_reset_hard(piix_t *dev) if (dev->type == 4) fregs[0x08] = (dev->rev & 0x08) ? 0x02 : (dev->rev & 0x07); else - fregs[0x08] = dev->rev; + fregs[0x08] = dev->rev; fregs[0x09] = 0x00; fregs[0x0a] = 0x01; fregs[0x0b] = 0x06; fregs[0x0e] = ((dev->type > 1) || (dev->rev != 2)) ? 0x80 : 0x00; @@ -1476,7 +1489,7 @@ static void /* On PIIX4, PIIX4E, and SMSC, APM is added by the ACPI device. */ if (dev->type < 4) { - dev->apm = device_add(&apm_pci_device); + dev->apm = device_add(&apm_pci_device); /* APM intercept handler to update PIIX/PIIX3 and PIIX4/4E/SMSC ACPI SMI status on APM SMI. */ io_sethandler(0x00b2, 0x0001, NULL, NULL, NULL, piix_apm_out, NULL, NULL, dev); } diff --git a/src/chipset/via_pipc.c b/src/chipset/via_pipc.c index 863388e2d..df3b26a8e 100644 --- a/src/chipset/via_pipc.c +++ b/src/chipset/via_pipc.c @@ -591,7 +591,7 @@ pipc_trap_update_paden(pipc_t *dev, uint8_t trap_id, /* Set up Primary Activity Detect I/O traps dynamically. */ if (enable && !trap->trap) { - trap->dev = dev; + trap->dev = dev; trap->trap = io_trap_add(pipc_trap_io_pact, trap); trap->sts_reg = &dev->acpi->regs.padsts; trap->en_reg = &dev->acpi->regs.paden;