diff --git a/src/include/86box/usb.h b/src/include/86box/usb.h index ab0549844..987eb1314 100644 --- a/src/include/86box/usb.h +++ b/src/include/86box/usb.h @@ -22,14 +22,25 @@ extern "C" { #endif -/* USB Host Controller device struct */ +typedef struct usb_t usb_t; + +/* USB device creation parameters struct */ typedef struct +{ + void (*raise_interrupt)(usb_t*, void*); + void* parent_priv; +} usb_params_t; + +/* USB Host Controller device struct */ +typedef struct usb_t { uint8_t uhci_io[32], ohci_mmio[4096]; uint16_t uhci_io_base; int uhci_enable, ohci_enable; uint32_t ohci_mem_base; mem_mapping_t ohci_mmio_mapping; + + usb_params_t* usb_params; } usb_t; /* USB endpoint device struct. Incomplete and unused. */ diff --git a/src/usb.c b/src/usb.c index e9702afa7..ca8ee1d38 100644 --- a/src/usb.c +++ b/src/usb.c @@ -47,6 +47,48 @@ usb_log(const char *fmt, ...) # define usb_log(fmt, ...) #endif +/* OHCI registers */ +enum +{ + OHCI_HcRevision = 0x00, + OHCI_HcControl = 0x04, + OHCI_HcCommandStatus = 0x08, + OHCI_HcInterruptStatus = 0x0C, + OHCI_HcInterruptEnable = 0x10, + OHCI_HcInterruptDisable = 0x14, + OHCI_HcHCCA = 0x18, + OHCI_HcPeriodCurrentED = 0x1C, + OHCI_HcControlHeadED = 0x20, + OHCI_HcControlCurrentED = 0x24, + OHCI_HcBulkHeadED = 0x28, + OHCI_HcBulkCurrentED = 0x2C, + OHCI_HcDoneHead = 0x30, + OHCI_HcFMInterval = 0x34, + OHCI_HcFmRemaining = 0x38, + OHCI_HcFmNumber = 0x3C, + OHCI_HcPeriodicStart = 0x40, + OHCI_HcLSThreshold = 0x44, + OHCI_HcRhDescriptorA = 0x48, + OHCI_HcRhDescriptorB = 0x4C, + OHCI_HcRhStatus = 0x50, + OHCI_HcRhPortStatus1 = 0x54, + OHCI_HcRhPortStatus2 = 0x58, + OHCI_HcRhPortStatus3 = 0x5C +}; + +static void +usb_interrupt_ohci(usb_t* usb) +{ + if (usb->ohci_mmio[OHCI_HcControl + 1] & 1) { + smi_raise(); + } + else if (usb->usb_params != NULL) { + if (usb->usb_params->parent_priv != NULL && usb->usb_params->raise_interrupt != NULL) { + usb->usb_params->raise_interrupt(usb, usb->usb_params->parent_priv); + } + } +} + static uint8_t uhci_reg_read(uint16_t addr, void *p) { @@ -131,35 +173,6 @@ uhci_update_io_mapping(usb_t *dev, uint8_t base_l, uint8_t base_h, int enable) io_sethandler(dev->uhci_io_base, 0x20, uhci_reg_read, NULL, NULL, uhci_reg_write, uhci_reg_writew, NULL, dev); } -/* OHCI registers */ -enum -{ - OHCI_HcRevision = 0x00, - OHCI_HcControl = 0x04, - OHCI_HcCommandStatus = 0x08, - OHCI_HcInterruptStatus = 0x0C, - OHCI_HcInterruptEnable = 0x10, - OHCI_HcInterruptDisable = 0x14, - OHCI_HcHCCA = 0x18, - OHCI_HcPeriodCurrentED = 0x1C, - OHCI_HcControlHeadED = 0x20, - OHCI_HcControlCurrentED = 0x24, - OHCI_HcBulkHeadED = 0x28, - OHCI_HcBulkCurrentED = 0x2C, - OHCI_HcDoneHead = 0x30, - OHCI_HcFMInterval = 0x34, - OHCI_HcFmRemaining = 0x38, - OHCI_HcFmNumber = 0x3C, - OHCI_HcPeriodicStart = 0x40, - OHCI_HcLSThreshold = 0x44, - OHCI_HcRhDescriptorA = 0x48, - OHCI_HcRhDescriptorB = 0x4C, - OHCI_HcRhStatus = 0x50, - OHCI_HcRhPortStatus1 = 0x54, - OHCI_HcRhPortStatus2 = 0x58, - OHCI_HcRhPortStatus3 = 0x5C -}; - static uint8_t ohci_mmio_read(uint32_t addr, void *p) { @@ -419,7 +432,7 @@ usb_close(void *priv) } static void * -usb_init(const device_t *info) +usb_init_ext(const device_t *info, void* params) { usb_t *dev; @@ -428,6 +441,8 @@ usb_init(const device_t *info) return (NULL); memset(dev, 0x00, sizeof(usb_t)); + dev->usb_params = (usb_params_t*)params; + mem_mapping_add(&dev->ohci_mmio_mapping, 0, 0, ohci_mmio_read, NULL, NULL, ohci_mmio_write, NULL, NULL, @@ -440,9 +455,9 @@ usb_init(const device_t *info) const device_t usb_device = { .name = "Universal Serial Bus", .internal_name = "usb", - .flags = DEVICE_PCI, + .flags = DEVICE_PCI | DEVICE_EXTPARAMS, .local = 0, - .init = usb_init, + .init_ext = usb_init_ext, .close = usb_close, .reset = usb_reset, { .available = NULL },