summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--payloads/libpayload/arch/armv7/timer.c47
-rw-r--r--payloads/libpayload/arch/powerpc/timer.c76
-rw-r--r--payloads/libpayload/arch/x86/timer.c52
-rw-r--r--payloads/libpayload/include/libpayload.h6
-rw-r--r--payloads/libpayload/libc/time.c72
5 files changed, 77 insertions, 176 deletions
diff --git a/payloads/libpayload/arch/armv7/timer.c b/payloads/libpayload/arch/armv7/timer.c
index 24b0a0fa34..9449c9feff 100644
--- a/payloads/libpayload/arch/armv7/timer.c
+++ b/payloads/libpayload/arch/armv7/timer.c
@@ -52,50 +52,3 @@ unsigned int get_cpu_speed(void)
return cpu_khz;
}
-
-static inline void _delay(unsigned long long delta)
-{
- /* FIXME */
-}
-
-/**
- * Delay for a specified number of nanoseconds.
- *
- * @param n Number of nanoseconds to delay for.
- */
-void ndelay(unsigned int n)
-{
- _delay((unsigned long long)n * cpu_khz / 1000000);
-}
-
-/**
- * Delay for a specified number of microseconds.
- *
- * @param n Number of microseconds to delay for.
- */
-void udelay(unsigned int n)
-{
- _delay((unsigned long long)n * cpu_khz / 1000);
-}
-
-/**
- * Delay for a specified number of milliseconds.
- *
- * @param m Number of milliseconds to delay for.
- */
-void mdelay(unsigned int m)
-{
- _delay((unsigned long long)m * cpu_khz);
-}
-
-/**
- * Delay for a specified number of seconds.
- *
- * @param s Number of seconds to delay for.
- */
-void delay(unsigned int s)
-{
- int i;
- for (i=0; i<1000; i++)
- _delay((unsigned long long)s * cpu_khz);
-}
diff --git a/payloads/libpayload/arch/powerpc/timer.c b/payloads/libpayload/arch/powerpc/timer.c
index ba824b0d57..fb181a4d63 100644
--- a/payloads/libpayload/arch/powerpc/timer.c
+++ b/payloads/libpayload/arch/powerpc/timer.c
@@ -33,7 +33,6 @@
*/
#include <libpayload.h>
-// #include <arch/rdtsc.h>
/**
* @ingroup arch
@@ -48,80 +47,19 @@ u32 cpu_khz;
*/
unsigned int get_cpu_speed(void)
{
-#if 0
- unsigned long long start, end;
-
- /* Set up the PPC port - disable the speaker, enable the T2 gate. */
- outb((inb(0x61) & ~0x02) | 0x01, 0x61);
-
- /* Set the PIT to Mode 0, counter 2, word access. */
- outb(0xB0, 0x43);
-
- /* Load the counter with 0xffff. */
- outb(0xff, 0x42);
- outb(0xff, 0x42);
-
- /* Read the number of ticks during the period. */
- start = rdtsc();
- while (!(inb(0x61) & 0x20)) ;
- end = rdtsc();
-
- /*
- * The clock rate is 1193180 Hz, the number of milliseconds for a
- * period of 0xffff is 1193180 / (0xFFFF * 1000) or .0182.
- * Multiply that by the number of measured clocks to get the kHz value.
- */
- cpu_khz = (unsigned int)((end - start) * 1193180U / (1000 * 0xffff));
-#else
+ /* FIXME */
cpu_khz = 200 * 1024;
-#endif
return cpu_khz;
}
-static inline void _delay(unsigned long long delta)
-{
-#if 0
- unsigned long long timeout = rdtsc() + delta;
- while (rdtsc() < timeout) ;
-#endif
-}
-
-/**
- * Delay for a specified number of nanoseconds.
- *
- * @param n Number of nanoseconds to delay for.
- */
-void ndelay(unsigned int n)
-{
- _delay(n * cpu_khz / 1000000);
-}
-
-/**
- * Delay for a specified number of microseconds.
- *
- * @param n Number of microseconds to delay for.
- */
-void udelay(unsigned int n)
+uint64_t timer_hz(void)
{
- _delay(n * cpu_khz / 1000);
+ /* FIXME */
+ return 0;
}
-/**
- * Delay for a specified number of milliseconds.
- *
- * @param m Number of milliseconds to delay for.
- */
-void mdelay(unsigned int m)
-{
- _delay(m * cpu_khz);
-}
-
-/**
- * Delay for a specified number of seconds.
- *
- * @param s Number of seconds to delay for.
- */
-void delay(unsigned int s)
+uint64_t timer_raw_value(void)
{
- _delay(s * cpu_khz * 1000);
+ /* FIXME */
+ return 0;
}
diff --git a/payloads/libpayload/arch/x86/timer.c b/payloads/libpayload/arch/x86/timer.c
index 40e81c4ced..e0cefb819a 100644
--- a/payloads/libpayload/arch/x86/timer.c
+++ b/payloads/libpayload/arch/x86/timer.c
@@ -28,8 +28,8 @@
*/
/**
- * @file i386/timer.c
- * i386 specific timer routines
+ * @file x86/timer.c
+ * x86 specific timer routines
*/
#include <libpayload.h>
@@ -39,7 +39,7 @@
* @ingroup arch
* Global variable containing the speed of the processor in KHz.
*/
-u32 cpu_khz;
+uint32_t cpu_khz;
/**
* Calculate the speed of the processor for use in delays.
@@ -77,50 +77,12 @@ unsigned int get_cpu_speed(void)
return cpu_khz;
}
-static inline void _delay(unsigned long long delta)
+uint64_t timer_hz(void)
{
- unsigned long long timeout = rdtsc() + delta;
- while (rdtsc() < timeout) ;
+ return lib_sysinfo.cpu_khz * 1000;
}
-/**
- * Delay for a specified number of nanoseconds.
- *
- * @param n Number of nanoseconds to delay for.
- */
-void ndelay(unsigned int n)
-{
- _delay((unsigned long long)n * cpu_khz / 1000000);
-}
-
-/**
- * Delay for a specified number of microseconds.
- *
- * @param n Number of microseconds to delay for.
- */
-void udelay(unsigned int n)
-{
- _delay((unsigned long long)n * cpu_khz / 1000);
-}
-
-/**
- * Delay for a specified number of milliseconds.
- *
- * @param m Number of milliseconds to delay for.
- */
-void mdelay(unsigned int m)
-{
- _delay((unsigned long long)m * cpu_khz);
-}
-
-/**
- * Delay for a specified number of seconds.
- *
- * @param s Number of seconds to delay for.
- */
-void delay(unsigned int s)
+uint64_t timer_raw_value(void)
{
- int i;
- for (i=0; i<1000; i++)
- _delay((unsigned long long)s * cpu_khz);
+ return rdtsc();
}
diff --git a/payloads/libpayload/include/libpayload.h b/payloads/libpayload/include/libpayload.h
index eaa0d0deeb..f23fb8763b 100644
--- a/payloads/libpayload/include/libpayload.h
+++ b/payloads/libpayload/include/libpayload.h
@@ -407,8 +407,12 @@ int get_multiboot_info(struct sysinfo_t *info);
int lib_get_sysinfo(void);
-/* Timer functions - defined by each architecture. */
+/* Timer functions. */
+/* Defined by each architecture. */
unsigned int get_cpu_speed(void);
+uint64_t timer_hz(void);
+uint64_t timer_raw_value(void);
+/* Generic. */
void ndelay(unsigned int n);
void udelay(unsigned int n);
void mdelay(unsigned int n);
diff --git a/payloads/libpayload/libc/time.c b/payloads/libpayload/libc/time.c
index 1503c45d99..7b6bf47cdf 100644
--- a/payloads/libpayload/libc/time.c
+++ b/payloads/libpayload/libc/time.c
@@ -46,21 +46,23 @@ static struct {
suseconds_t usecs;
} clock;
-#define TICKS_PER_SEC (cpu_khz * 1000)
-#define TICKS_PER_USEC (cpu_khz / 1000)
-
-#ifdef CONFIG_ARCH_X86
static void update_clock(void)
{
- u64 delta = rdtsc() - clock.ticks;
+ u64 delta = timer_raw_value() - clock.ticks;
int secs;
+ static uint64_t ticks_per_sec = 0;
+ static uint64_t ticks_per_usec = 0;
+ if (!ticks_per_sec) {
+ ticks_per_sec = timer_hz();
+ ticks_per_usec = timer_hz() / 1000000;
+ }
clock.ticks += delta;
- secs = (int) (delta / TICKS_PER_SEC);
+ secs = (int) (delta / ticks_per_sec);
clock.secs += secs;
- delta -= (secs * TICKS_PER_SEC);
- clock.usecs += (int) (delta / TICKS_PER_USEC);
+ delta -= (secs * ticks_per_sec);
+ clock.usecs += (int)(delta / ticks_per_usec);
if (clock.usecs > 1000000) {
clock.usecs -= 1000000;
@@ -110,15 +112,11 @@ static void gettimeofday_init(void)
clock.secs = (days * 86400) + (tm.tm_hour * 3600) +
(tm.tm_min * 60) + tm.tm_sec;
}
-#endif // CONFIG_NVRAM
-
#else
-static void update_clock(void)
-{
-}
-
static void gettimeofday_init(void)
{
+ /* Record the number of ticks */
+ clock.ticks = timer_raw_value();
}
#endif
@@ -145,3 +143,49 @@ int gettimeofday(struct timeval *tv, void *tz)
return 0;
}
+
+static inline void _delay(uint64_t delta)
+{
+ uint64_t start = timer_raw_value();
+ while (timer_raw_value() - start < delta) ;
+}
+
+/**
+ * Delay for a specified number of nanoseconds.
+ *
+ * @param n Number of nanoseconds to delay for.
+ */
+void ndelay(unsigned int n)
+{
+ _delay((uint64_t)n * timer_hz() / 1000000000);
+}
+
+/**
+ * Delay for a specified number of microseconds.
+ *
+ * @param n Number of microseconds to delay for.
+ */
+void udelay(unsigned int n)
+{
+ _delay((uint64_t)n * timer_hz() / 1000000);
+}
+
+/**
+ * Delay for a specified number of milliseconds.
+ *
+ * @param m Number of milliseconds to delay for.
+ */
+void mdelay(unsigned int m)
+{
+ _delay((uint64_t)m * timer_hz() / 1000);
+}
+
+/**
+ * Delay for a specified number of seconds.
+ *
+ * @param s Number of seconds to delay for.
+ */
+void delay(unsigned int s)
+{
+ _delay((uint64_t)s * timer_hz());
+}