aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2009-10-22 22:30:37 -0400
committerKevin O'Connor <kevin@koconnor.net>2009-10-22 22:30:37 -0400
commit89eb6241e51bc825cfbc1292802a960dcb48d778 (patch)
tree8d9f7c0b09717a30c3b81851f6233e78e2b5273c /src
parent77d227b650c50a7dd0dbaf0ff2ec8681084ddc5f (diff)
downloadseabios-89eb6241e51bc825cfbc1292802a960dcb48d778.tar.gz
Handle tsc rollover.
Handle case where timetamp counter overflows while waiting.
Diffstat (limited to 'src')
-rw-r--r--src/ata.c6
-rw-r--r--src/cdrom.c2
-rw-r--r--src/clock.c12
-rw-r--r--src/ps2port.c2
-rw-r--r--src/usb-ohci.c4
-rw-r--r--src/usb-uhci.c2
-rw-r--r--src/util.h3
7 files changed, 17 insertions, 14 deletions
diff --git a/src/ata.c b/src/ata.c
index 2312f7d0..050269e7 100644
--- a/src/ata.c
+++ b/src/ata.c
@@ -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;
}
diff --git a/src/util.h b/src/util.h
index 6cf27ac0..f95cdb59 100644
--- a/src/util.h
+++ b/src/util.h
@@ -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);