From 3f461afeeb25194c359a6ba764f1966d0bbd0662 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 5 May 2023 00:28:08 +0600 Subject: [PATCH] usb: start hooking up USB interrupts to chipsets --- src/chipset/sis_5571.c | 37 ++++++++++++++++++++++++++++++++++++- src/include/86box/usb.h | 2 ++ src/usb.c | 3 +++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/chipset/sis_5571.c b/src/chipset/sis_5571.c index 0f77a1a07..aa8ea62f3 100644 --- a/src/chipset/sis_5571.c +++ b/src/chipset/sis_5571.c @@ -83,6 +83,8 @@ typedef struct sis_5571_t { smram_t *smram; usb_t *usb; + usb_params_t usb_params; + } sis_5571_t; static void @@ -638,6 +640,36 @@ pci_isa_bridge_read(int func, int addr, void *priv) } } +static void +sis_5571_usb_raise_interrupt(usb_t* usb, void* priv) +{ + sis_5571_t *dev = (sis_5571_t *) priv; + + if (dev->pci_conf_sb[0][0x68] & 0x80) { + /* TODO: Is the normal PCI interrupt inhibited when USB IRQ remapping is enabled? */ + switch (dev->pci_conf_sb[0][0x68] & 0x0F) { + case 0x00: + case 0x01: + case 0x02: + case 0x08: + case 0x0d: + break; + default: + picint(1 << dev->pci_conf_sb[0][0x68] & 0x0F); + break; + } + } else { + pci_set_irq(dev->sb_pci_slot, PCI_INTA); + } +} + +static uint8_t +sis_5571_usb_handle_smi(usb_t* usb, void* priv) +{ + /* Left unimplemented for now. */ + return 1; +} + static void sis_5571_reset(void *priv) { @@ -722,7 +754,10 @@ sis_5571_init(const device_t *info) dev->ide_drive[1] = device_add_inst(&sff8038i_device, 2); /* USB */ - dev->usb = device_add(&usb_device); + dev->usb_params.parent_priv = dev; + dev->usb_params.raise_interrupt = sis_5571_usb_raise_interrupt; + dev->usb_params.smi_handle = sis_5571_usb_handle_smi; + dev->usb = device_add_parameters(&usb_device, &dev->usb_params); sis_5571_reset(dev); diff --git a/src/include/86box/usb.h b/src/include/86box/usb.h index cf5938a3d..7860ada3b 100644 --- a/src/include/86box/usb.h +++ b/src/include/86box/usb.h @@ -28,6 +28,8 @@ typedef struct usb_t usb_t; typedef struct { void (*raise_interrupt)(usb_t*, void*); + /* Handle (but do not raise) SMI. Returns 1 if SMI can be raised, 0 otherwise. */ + uint8_t (*smi_handle)(usb_t*, void*); void* parent_priv; } usb_params_t; diff --git a/src/usb.c b/src/usb.c index 7dd8341c3..03fe8a9a6 100644 --- a/src/usb.c +++ b/src/usb.c @@ -80,6 +80,9 @@ static void usb_interrupt_ohci(usb_t* usb) { if (usb->ohci_mmio[OHCI_HcControl + 1] & 1) { + if (usb->usb_params && usb->usb_params->smi_handle && !usb->usb_params->smi_handle(usb, usb->usb_params->parent_priv)) + return; + smi_raise(); } else if (usb->usb_params != NULL) {