diff options
author | Helge Deller <deller@gmx.de> | 2023-10-28 07:56:31 +0200 |
---|---|---|
committer | Helge Deller <deller@gmx.de> | 2023-10-31 08:26:22 +0100 |
commit | 539ffaa1b9e7628cfacdea63d11b270acb945411 (patch) | |
tree | 8de3416c64c1143f1685f058f69f046e7167a88d | |
parent | 649de06ac95bc097764042fba42a2dcde992f046 (diff) | |
download | seabios-hppa-539ffaa1b9e7628cfacdea63d11b270acb945411.zip seabios-hppa-539ffaa1b9e7628cfacdea63d11b270acb945411.tar.gz seabios-hppa-539ffaa1b9e7628cfacdea63d11b270acb945411.tar.bz2 |
parisc: Add timer2() wait function to cope with 32-bit timer limit
Signed-off-by: Helge Deller <deller@gmx.de>
-rw-r--r-- | src/hw/usb-ohci.c | 25 | ||||
-rw-r--r-- | src/parisc/parisc.c | 2 | ||||
-rw-r--r-- | src/parisc/timer.c | 27 | ||||
-rw-r--r-- | src/util.h | 7 |
4 files changed, 54 insertions, 7 deletions
diff --git a/src/hw/usb-ohci.c b/src/hw/usb-ohci.c index c839d11..cc35bae 100644 --- a/src/hw/usb-ohci.c +++ b/src/hw/usb-ohci.c @@ -64,13 +64,15 @@ ohci_hub_reset(struct usbhub_s *hub, u32 port) struct usb_ohci_s *cntl = container_of(hub->cntl, struct usb_ohci_s, usb); writel(&cntl->regs->roothub_portstatus[port], RH_PS_PRS); u32 sts; - u32 end = timer_calc(USB_TIME_DRSTR * 2); + struct wait_t end; + + timer_calc2_ms(&end, USB_TIME_DRSTR * 2); for (;;) { sts = readl(&cntl->regs->roothub_portstatus[port]); if (!(sts & RH_PS_PRS)) // XXX - need to ensure USB_TIME_DRSTR time in reset? break; - if (timer_check(end)) { + if (timer_check2(&end)) { // Timeout. warn_timeout(); ohci_hub_disconnect(hub, port); @@ -128,11 +130,13 @@ ohci_waittick(struct ohci_regs *regs) barrier(); struct ohci_hcca *hcca = (void*)readl(®s->hcca); u32 startframe = hcca->frame_no; - u32 end = timer_calc(1000 * 5); + struct wait_t end; + + timer_calc2_ms(&end, 1000 * 5); for (;;) { if (hcca->frame_no != startframe) break; - if (timer_check(end)) { + if (timer_check2(&end)) { warn_timeout(); return; } @@ -442,11 +446,20 @@ ohci_realloc_pipe(struct usbdevice_s *usbdev, struct usb_pipe *upipe static int wait_ed(struct ohci_ed *ed, int timeout) { - u32 end = timer_calc(timeout); + struct wait_t end; + + timer_calc2_ms(&end, timeout); +#if 0 + while (1) { + timer_calc2_ms(&end, 1000); + while (!timer_check2(&end)) { }; + dprintf(1, "Tick\n"); + } +#endif for (;;) { if ((le32_to_cpu(ed->hwHeadP) & ~(ED_C|ED_H)) == le32_to_cpu(ed->hwTailP)) return 0; - if (timer_check(end)) { + if (timer_check2(&end)) { warn_timeout(); dprintf(1, "ohci ed info=%x tail=%x head=%x next=%x\n", le32_to_cpu(ed->hwINFO), le32_to_cpu(ed->hwTailP), diff --git a/src/parisc/parisc.c b/src/parisc/parisc.c index 92d044e..9c8375d 100644 --- a/src/parisc/parisc.c +++ b/src/parisc/parisc.c @@ -2917,8 +2917,8 @@ void __VISIBLE start_parisc_firmware(void) find_serial_pci_card(); serial_setup(); + // usb_setup(); // ohci_setup(); - usb_setup(); block_setup(); /* find SCSI PCI card when running on Astro or Dino */ diff --git a/src/parisc/timer.c b/src/parisc/timer.c index 9605f91..c3169f3 100644 --- a/src/parisc/timer.c +++ b/src/parisc/timer.c @@ -94,6 +94,33 @@ timer_calc_usec(u32 usecs) return ((usecs * PAGE0->mem_10msec / 10) / 1000) + timer_read(); } +void +timer_calc2_ms(struct wait_t *w, u32 msecs) +{ + w->usecs = msecs / 1000; + w->end = msecs % 1000; + if (w->end == 0) { + w->end = 1000; + w->usecs -= 1; + } + w->end = timer_calc(w->end); +} + +int +timer_check2(struct wait_t *w) +{ + s32 remain; + + /* return 1 if timed out */ + remain = (s32)(timer_read() - w->end); + if (remain <= 0) + return 0; + if (w->usecs == 0) + return 1; + w->usecs -= 1; + w->end = timer_calc(1000); + return 0; +} void pit_setup(void) @@ -71,6 +71,13 @@ u32 irqtimer_calc(u32 msecs); int irqtimer_check(u32 end); void handle_1586(struct bregs *regs); +struct wait_t { + u32 usecs; + u32 end; +}; +void timer_calc2_ms(struct wait_t *w, u32 msecs); +int timer_check2(struct wait_t *w); + // fw/acpi.c void acpi_setup(void); |