diff --git a/src/chipset/intel_piix.c b/src/chipset/intel_piix.c index d67eeb0471..89f82d9a5a 100644 --- a/src/chipset/intel_piix.c +++ b/src/chipset/intel_piix.c @@ -1535,6 +1535,19 @@ piix_speed_changed(void *priv) timer_on_auto(&dev->fast_off_timer, ((double) cpu_fast_off_val + 1) * dev->fast_off_period); } +static void +piix_smsc_usb_smi_raise(void* priv) +{ + piix_t *dev = (piix_t *) priv; + if (!dev) + return; + + if ((dev->acpi->regs.glben & 1)) { + dev->acpi->regs.glbsts |= 2; + acpi_raise_smi(dev->acpi, 1); + } +} + static void * piix_init(const device_t *info) { @@ -1554,6 +1567,9 @@ piix_init(const device_t *info) piix_log("PIIX%i: Added to slot: %02X\n", dev->type, dev->pci_slot); params.pci_dev = &dev->pci_slot; params.pci_conf = &dev->regs[2][0]; + params.do_smi_raise = piix_smsc_usb_smi_raise; + params.priv = dev; + params.do_pci_irq = 0; dev->bm[0] = device_add_inst(&sff8038i_device, 1); dev->bm[1] = device_add_inst(&sff8038i_device, 2); diff --git a/src/chipset/sis_5571_h2p.c b/src/chipset/sis_5571_h2p.c index 4a4ee9b83d..b0b43310ac 100644 --- a/src/chipset/sis_5571_h2p.c +++ b/src/chipset/sis_5571_h2p.c @@ -276,6 +276,9 @@ sis_5571_host_to_pci_write(int addr, uint8_t val, void *priv) break; case 0x95: /* Test mode control */ + dev->sis->test_mode_reg = val & 0xfb; + pclog("SiS: USB SMI# %sabled\n", (dev->sis->test_mode_reg & 0x10) ? "en" : "dis"); + break; case 0x96: /* Time slot and Programmable 10-bit I/O port definition */ dev->pci_conf[addr] = val & 0xfb; break; @@ -309,7 +312,7 @@ sis_5571_host_to_pci_read(int addr, void *priv) const sis_5571_host_to_pci_t *dev = (sis_5571_host_to_pci_t *) priv; uint8_t ret = 0xff; - ret = dev->pci_conf[addr]; + ret = (addr == 0x95) ? dev->sis->test_mode_reg : dev->pci_conf[addr]; sis_5571_host_to_pci_log("SiS 5571 H2P: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); @@ -410,6 +413,8 @@ sis_5571_host_to_pci_reset(void *priv) dev->pci_conf[0xa2] = 0xff; dev->pci_conf[0xa3] = 0x00; + dev->sis->test_mode_reg = 0x10; + cpu_cache_ext_enabled = 0; cpu_update_waitstates(); diff --git a/src/chipset/sis_5572_usb.c b/src/chipset/sis_5572_usb.c index a50c8d615d..241cd0f9ff 100644 --- a/src/chipset/sis_5572_usb.c +++ b/src/chipset/sis_5572_usb.c @@ -66,7 +66,7 @@ sis_5572_usb_log(const char *fmt, ...) #endif typedef struct sis_5572_usb_t { - uint8_t rev; + uint8_t rev, irq_state; uint8_t usb_unk_regs[256]; uint8_t pci_conf[256]; @@ -78,6 +78,30 @@ typedef struct sis_5572_usb_t { sis_55xx_common_t *sis; } sis_5572_usb_t; +void +sis_5572_usb_smi_raise(void* priv) +{ + sis_5572_usb_t *dev = (sis_5572_usb_t *) priv; + + if (dev->sis->usb_enabled && (dev->sis->test_mode_reg & 0x10)) { + dev->sis->test_mode_reg |= 0x8; + smi_raise(); + } +} + +void +sis_5572_usb_pci_irq(void *priv, int level) +{ + sis_5572_usb_t *dev = (sis_5572_usb_t *) priv; + + if (dev->sis->usb_enabled) { + if (level) + pci_set_mirq(PCI_MIRQ3, level, &dev->irq_state); + else + pci_clear_mirq(PCI_MIRQ3, level, &dev->irq_state); + } +} + /* SiS 5572 unknown I/O port (second USB PCI BAR). */ static void sis_5572_usb_unk_write(uint16_t addr, uint8_t val, void *priv) @@ -275,8 +299,11 @@ sis_5572_usb_init(UNUSED(const device_t *info)) /* USB */ usb_param.pci_conf = dev->pci_conf; - usb_param.pci_dev = dev->sis->sb_southbridge_slot; - dev->usb = device_add(&usb_device); + usb_param.pci_dev = dev->sis->sb_southbridge_slot; + usb_param.priv = dev; + usb_param.do_smi_raise = sis_5572_usb_smi_raise; + usb_param.do_pci_irq = sis_5572_usb_pci_irq; + dev->usb = device_add_params(&usb_device, &usb_param); ohci_register_usb(dev->usb); sis_5572_usb_reset(dev); diff --git a/src/chipset/sis_5581_h2p.c b/src/chipset/sis_5581_h2p.c index 30bd70bfea..08451ecc0b 100644 --- a/src/chipset/sis_5581_h2p.c +++ b/src/chipset/sis_5581_h2p.c @@ -389,7 +389,8 @@ sis_5581_host_to_pci_write(int addr, uint8_t val, void *priv) break; case 0x95: - dev->pci_conf[addr] = val & 0xfb; + dev->sis->test_mode_reg = val & 0xfb; + pclog("SiS: USB SMI# %sabled\n", (dev->sis->test_mode_reg & 0x10) ? "en" : "dis"); break; case 0x96: @@ -418,7 +419,7 @@ sis_5581_host_to_pci_read(int addr, void *priv) const sis_5581_host_to_pci_t *dev = (sis_5581_host_to_pci_t *) priv; uint8_t ret = 0xff; - ret = dev->pci_conf[addr]; + ret = (addr == 0x95) ? dev->sis->test_mode_reg : dev->pci_conf[addr]; sis_5581_host_to_pci_log("SiS 5581 H2P: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); @@ -478,6 +479,8 @@ sis_5581_host_to_pci_reset(void *priv) dev->pci_conf[0xa1] = 0x00; dev->pci_conf[0xa2] = 0xff; dev->pci_conf[0xa3] = 0x00; + + dev->sis->test_mode_reg = 0x00; cpu_cache_ext_enabled = 0; cpu_update_waitstates(); diff --git a/src/include/86box/sis_55xx.h b/src/include/86box/sis_55xx.h index e2ac6bd95d..d33cb8a713 100644 --- a/src/include/86box/sis_55xx.h +++ b/src/include/86box/sis_55xx.h @@ -22,6 +22,7 @@ typedef struct uint8_t *sb_southbridge_slot; uint8_t ide_bits_1_3_writable; uint8_t usb_enabled; + uint8_t test_mode_reg; /* USB SMI control. */ uint8_t *pmu_regs; diff --git a/src/include/86box/usb.h b/src/include/86box/usb.h index f5c3ec3c83..0404c4f253 100644 --- a/src/include/86box/usb.h +++ b/src/include/86box/usb.h @@ -28,6 +28,10 @@ typedef struct usb_device_c usb_device_c; typedef struct usb_params_t { uint8_t* pci_dev; uint8_t* pci_conf; + + void* priv; /* Implementation-specific behaviour. */ + void (*do_smi_raise)(void* priv); + void (*do_pci_irq)(void* priv, int level); } usb_params_t; typedef struct usb_t { diff --git a/src/usb/usb_hid.c b/src/usb/usb_hid.c index adec077fd0..d4ba52620f 100644 --- a/src/usb/usb_hid.c +++ b/src/usb/usb_hid.c @@ -1235,7 +1235,7 @@ usb_hid_poll_wrapper(void *priv) mouse_subtract_coords(&delta_x, &delta_y, &overflow_x, &overflow_y, -128, 127, 1, 0); - mouse_subtract_z(&delta_z, -8, 7, 1); + mouse_subtract_z(&delta_z, -8, 7, 0); mouse_enq(hid, delta_x, delta_y, delta_z, b, 0); return 1; } @@ -1505,7 +1505,7 @@ usb_device_hid_handle_data(usb_device_c *device, USBPacket *p) case USB_TOKEN_IN: if (p->devep == 1) { if ((device->type == USB_HID_TYPE_MOUSE) || (device->type == USB_HID_TYPE_TABLET)) { - pclog("USB MOUSE POLLING\n"); + //pclog("USB MOUSE POLLING\n"); ret = usb_mouse_poll((usb_device_hid *) device, p->data, 0); } else { goto fail; diff --git a/src/usb/usb_ohci_bochs.c b/src/usb/usb_ohci_bochs.c index 152e68e911..c450c51c4e 100644 --- a/src/usb/usb_ohci_bochs.c +++ b/src/usb/usb_ohci_bochs.c @@ -196,6 +196,8 @@ typedef struct { bool oci; // 1 bit OverCurrentIndicator = 0b R RW bool lps; // 1 bit LocalPowerStatus(r) = 0b RW R } HcRhStatus; // = 0x00000000 + + uint32_t HceInput, HceOutput, HceControl, HceStatus; } op_regs; struct { @@ -235,6 +237,10 @@ typedef struct { bool ohci_enable; uint32_t ohci_mem_base; + + void (*do_smi_raise)(void *priv); + void (*do_pci_irq)(void *priv, int level); + void* card_priv; } bx_ohci_core_t; const char *usb_ohci_port_name[] = { @@ -301,13 +307,19 @@ void usb_ohci_update_irq(bx_ohci_core_t* hub) (hub->op_regs.HcInterruptStatus & hub->op_regs.HcInterruptEnable)) { level = 1; } - if (hub->op_regs.HcControl.ir && level) - smi_raise(); + if (hub->op_regs.HcControl.ir && level) { + if (hub->do_smi_raise && hub->card_priv) + hub->do_smi_raise(hub->card_priv); + else + smi_raise(); + } else if (!hub->op_regs.HcControl.ir) { - if (level) + if (hub->do_pci_irq) + hub->do_pci_irq(hub->card_priv, level); + else if (level) pci_set_irq(*hub->devfunc, hub->pci_conf[0x3d], &hub->irq_state); else - pci_set_irq(*hub->devfunc, hub->pci_conf[0x3d], &hub->irq_state); + pci_clear_irq(*hub->devfunc, hub->pci_conf[0x3d], &hub->irq_state); } } @@ -767,6 +779,26 @@ uint32_t usb_ohci_mem_read(uint32_t addr, void *priv) | (hub->usb_port[p].HcRhPortStatus.ccs ? (1 << 0) : 0); break; + case 0x100: { + val = (hub->op_regs.HceControl & 0xFF) | ((!!mem_a20_key) << 8); + break; + } + + case 0x104: { + val = hub->op_regs.HceInput; + break; + } + + case 0x108: { + val = hub->op_regs.HceOutput; + break; + } + + case 0x10C: { + val = hub->op_regs.HceStatus; + break; + } + default: BX_ERROR(("unsupported read from address=0x%08X!", (Bit32u)addr)); break; @@ -836,7 +868,10 @@ void usb_ohci_mem_write(uint32_t addr, uint32_t value, void* priv) hub->op_regs.HcInterruptStatus |= 0x40000000; if ((hub->op_regs.HcInterruptEnable & 0xC0000000) == 0xC0000000) { pclog("Assert SMI#\n"); - smi_raise(); + if (hub->do_smi_raise && hub->card_priv) + hub->do_smi_raise(hub->card_priv); + else + smi_raise(); } } if (value & (1<< 2)) hub->op_regs.HcCommandStatus.blf = 1; @@ -1094,6 +1129,25 @@ void usb_ohci_mem_write(uint32_t addr, uint32_t value, void* priv) break; } + case 0x100: { + hub->op_regs.HceControl = value; + break; + } + + case 0x104: { + hub->op_regs.HceInput = value; + break; + } + + case 0x108: { + hub->op_regs.HceOutput = value; + break; + } + + case 0x10C: { + hub->op_regs.HceStatus = value; + break; + } default: BX_ERROR(("unsupported write to address=0x%08X, val = 0x%08X!", (Bit32u)addr, value)); @@ -1593,6 +1647,9 @@ usb_ohci_init(UNUSED(const device_t *info)) if (usb_params) { hub->devfunc = usb_params->pci_dev; hub->pci_conf = usb_params->pci_conf; + hub->do_smi_raise = usb_params->do_smi_raise; + hub->card_priv = usb_params->priv; + hub->do_pci_irq = usb_params->do_pci_irq; } timer_add(&hub->timer, usb_ohci_timer, hub, 0); timer_on_auto(&hub->timer, 1000);