aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHelge Deller <deller@gmx.de>2023-10-28 07:56:31 +0200
committerHelge Deller <deller@gmx.de>2023-10-31 08:26:22 +0100
commit539ffaa1b9e7628cfacdea63d11b270acb945411 (patch)
tree8de3416c64c1143f1685f058f69f046e7167a88d
parent649de06ac95bc097764042fba42a2dcde992f046 (diff)
downloadseabios-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.c25
-rw-r--r--src/parisc/parisc.c2
-rw-r--r--src/parisc/timer.c27
-rw-r--r--src/util.h7
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(&regs->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)
diff --git a/src/util.h b/src/util.h
index 0de3522..dd919a8 100644
--- a/src/util.h
+++ b/src/util.h
@@ -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);