diff options
author | Kevin O'Connor <kevin@koconnor.net> | 2009-10-22 22:30:37 -0400 |
---|---|---|
committer | Kevin O'Connor <kevin@koconnor.net> | 2009-10-22 22:30:37 -0400 |
commit | 89eb6241e51bc825cfbc1292802a960dcb48d778 (patch) | |
tree | 8d9f7c0b09717a30c3b81851f6233e78e2b5273c /src | |
parent | 77d227b650c50a7dd0dbaf0ff2ec8681084ddc5f (diff) | |
download | seabios-89eb6241e51bc825cfbc1292802a960dcb48d778.tar.gz |
Handle tsc rollover.
Handle case where timetamp counter overflows while waiting.
Diffstat (limited to 'src')
-rw-r--r-- | src/ata.c | 6 | ||||
-rw-r--r-- | src/cdrom.c | 2 | ||||
-rw-r--r-- | src/clock.c | 12 | ||||
-rw-r--r-- | src/ps2port.c | 2 | ||||
-rw-r--r-- | src/usb-ohci.c | 4 | ||||
-rw-r--r-- | src/usb-uhci.c | 2 | ||||
-rw-r--r-- | src/util.h | 3 |
7 files changed, 17 insertions, 14 deletions
@@ -36,7 +36,7 @@ await_ide(u8 mask, u8 flags, u16 base, u16 timeout) u8 status = inb(base+ATA_CB_STAT); if ((status & mask) == flags) return status; - if (rdtscll() > end) { + if (check_time(end)) { dprintf(1, "IDE time out\n"); return -1; } @@ -107,7 +107,7 @@ ata_reset(struct drive_s *drive_g) if (inb(iobase1 + ATA_CB_DH) == ATA_CB_DH_DEV1) break; // Change drive request failed to take effect - retry. - if (rdtscll() > end) { + if (check_time(end)) { dprintf(1, "ata_reset slave time out\n"); goto done; } @@ -649,7 +649,7 @@ powerup_await_non_bsy(u16 base, u64 end) dprintf(1, "powerup IDE floating\n"); return orstatus; } - if (rdtscll() > end) { + if (check_time(end)) { dprintf(1, "powerup IDE time out\n"); return -1; } diff --git a/src/cdrom.c b/src/cdrom.c index ba533d0f..8d1ec9ad 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -228,7 +228,7 @@ atapi_is_ready(struct drive_s *drive_g) int in_progress = 0; u64 end = calc_future_tsc(5000); for (;;) { - if (rdtscll() > end) { + if (check_time(end)) { dprintf(1, "read capacity failed\n"); return -1; } diff --git a/src/clock.c b/src/clock.c index 0592a4ec..7735c70a 100644 --- a/src/clock.c +++ b/src/clock.c @@ -93,11 +93,11 @@ calibrate_tsc() } static void -tscsleep(u64 diff) +tscdelay(u64 diff) { u64 start = rdtscll(); u64 end = start + diff; - while (rdtscll() <= end) + while (!check_time(end)) cpu_relax(); } @@ -105,19 +105,19 @@ void ndelay(u32 count) { u32 khz = GET_GLOBAL(cpu_khz); - tscsleep(count * khz / 1000000); + tscdelay(count * khz / 1000000); } void udelay(u32 count) { u32 khz = GET_GLOBAL(cpu_khz); - tscsleep(count * khz / 1000); + tscdelay(count * khz / 1000); } void mdelay(u32 count) { u32 khz = GET_GLOBAL(cpu_khz); - tscsleep(count * khz); + tscdelay(count * khz); } // Return the TSC value that is 'msecs' time in the future. @@ -156,7 +156,7 @@ rtc_updating() do { if ((inb_cmos(CMOS_STATUS_A) & RTC_A_UIP) == 0) return 0; - } while (rdtscll() <= end); + } while (!check_time(end)); // update-in-progress never transitioned to 0 return -1; diff --git a/src/ps2port.c b/src/ps2port.c index 01e8b3d6..25d45446 100644 --- a/src/ps2port.c +++ b/src/ps2port.c @@ -152,7 +152,7 @@ ps2_recvbyte(int aux, int needack, int timeout) { u64 end = calc_future_tsc(timeout); for (;;) { - if (rdtscll() > end) { + if (check_time(end)) { dprintf(1, "ps2_recvbyte timeout\n"); return -1; } diff --git a/src/usb-ohci.c b/src/usb-ohci.c index f1ca559d..71202f84 100644 --- a/src/usb-ohci.c +++ b/src/usb-ohci.c @@ -34,7 +34,7 @@ start_ohci(struct usb_s *cntl, struct ohci_hcca *hcca) u32 status = readl(&cntl->ohci.regs->cmdstatus); if (! status & OHCI_HCR) break; - if (rdtscll() > end) { + if (check_time(end)) { dprintf(1, "Timeout on ohci software reset\n"); return -1; } @@ -181,7 +181,7 @@ wait_ed(struct ohci_ed *ed) for (;;) { if (ed->hwHeadP == ed->hwTailP) return 0; - if (rdtscll() > end) { + if (check_time(end)) { dprintf(1, "Timeout on wait_ed %p\n", ed); return -1; } diff --git a/src/usb-uhci.c b/src/usb-uhci.c index 5829069c..14a53007 100644 --- a/src/usb-uhci.c +++ b/src/usb-uhci.c @@ -160,7 +160,7 @@ wait_qh(struct uhci_qh *qh) for (;;) { if (qh->element & UHCI_PTR_TERM) return 0; - if (rdtscll() > end) { + if (check_time(end)) { dprintf(1, "Timeout on wait_qh %p\n", qh); return -1; } @@ -214,6 +214,9 @@ void serial_setup(); void lpt_setup(); // clock.c +static inline int check_time(u64 end) { + return (s64)(rdtscll() - end) > 0; +} void timer_setup(); void ndelay(u32 count); void udelay(u32 count); |