Merge pull request #3316 from Cacodemon345/usb-work

usb: More work on frame timing and events
This commit is contained in:
Miran Grča
2023-05-06 20:36:11 +02:00
committed by GitHub
3 changed files with 49 additions and 20 deletions

View File

@@ -1430,7 +1430,7 @@ ali7101_read(int func, int addr, void *priv)
}
static void
ali5237_usb_raise_interrupt(void *priv)
ali5237_usb_raise_interrupt(usb_t* usb, void *priv)
{
ali1543_t *dev = (ali1543_t *) priv;

View File

@@ -36,7 +36,13 @@ typedef struct
/* USB Host Controller device struct */
typedef struct usb_t
{
uint8_t uhci_io[32], ohci_mmio[4096];
union
{
uint8_t ohci_mmio[4096];
uint16_t ohci_mmio_w[2048];
uint32_t ohci_mmio_l[1024];
};
uint8_t uhci_io[32];
uint16_t uhci_io_base;
int uhci_enable, ohci_enable;
uint32_t ohci_mem_base;

View File

@@ -63,7 +63,7 @@ enum
OHCI_HcBulkHeadED = 0x28,
OHCI_HcBulkCurrentED = 0x2C,
OHCI_HcDoneHead = 0x30,
OHCI_HcFMInterval = 0x34,
OHCI_HcFmInterval = 0x34,
OHCI_HcFmRemaining = 0x38,
OHCI_HcFmNumber = 0x3C,
OHCI_HcPeriodicStart = 0x40,
@@ -223,10 +223,50 @@ ohci_mmio_read(uint32_t addr, void *p)
return ret;
}
void
ohci_set_interrupt(usb_t* usb, uint8_t bit)
{
if (!(usb->ohci_mmio[OHCI_HcInterruptEnable + 3] & 0x80))
return;
if (!(usb->ohci_mmio[OHCI_HcInterruptEnable] & bit))
return;
if (usb->ohci_mmio[OHCI_HcInterruptDisable] & bit)
return;
usb->ohci_mmio[OHCI_HcInterruptStatus] |= bit;
usb_interrupt_ohci(usb);
}
void
ohci_end_of_frame(usb_t* dev)
{
/* TODO: Put endpoint and transfer descriptor processing here. */
}
void
ohci_start_of_frame(usb_t* dev)
{
ohci_set_interrupt(dev, OHCI_HcInterruptEnable_SO);
}
void
ohci_update_frame_counter(void* priv)
{
usb_t *dev = (usb_t *) priv;
dev->ohci_mmio_w[OHCI_HcFmRemaining / 2] &= 0x3fff;
if (dev->ohci_mmio_w[OHCI_HcFmRemaining / 2] == 0) {
ohci_end_of_frame(dev);
dev->ohci_mmio_w[OHCI_HcFmRemaining / 2] = dev->ohci_mmio_w[OHCI_HcFmInterval / 2] & 0x3fff;
dev->ohci_mmio_l[OHCI_HcFmRemaining / 4] &= ~(1 << 31);
dev->ohci_mmio_l[OHCI_HcFmRemaining / 4] |= dev->ohci_mmio_l[OHCI_HcFmInterval / 4] & (1 << 31);
dev->ohci_mmio_w[OHCI_HcFmNumber / 2]++;
ohci_start_of_frame(dev);
}
if (dev->ohci_mmio_w[OHCI_HcFmRemaining / 2]) dev->ohci_mmio_w[OHCI_HcFmRemaining / 2]--;
timer_on_auto(&dev->ohci_frame_timer, 1. / (12. * 1000. * 1000.));
}
void
@@ -257,23 +297,6 @@ ohci_port_reset_callback_2(void* priv)
dev->ohci_mmio[OHCI_HcRhPortStatus2] &= ~0x10;
dev->ohci_mmio[OHCI_HcRhPortStatus2 + 2] |= 0x10;
}
void
ohci_set_interrupt(usb_t* usb, uint8_t bit)
{
if (!(usb->ohci_mmio[OHCI_HcInterruptEnable + 3] & 0x80))
return;
if (!(usb->ohci_mmio[OHCI_HcInterruptEnable] & bit))
return;
if (usb->ohci_mmio[OHCI_HcInterruptDisable] & bit)
return;
usb->ohci_mmio[OHCI_HcInterruptStatus] |= bit;
usb_interrupt_ohci(usb);
}
static void
ohci_mmio_write(uint32_t addr, uint8_t val, void *p)
{