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 -// #include /** * @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) +uint64_t timer_hz(void) { -#if 0 - unsigned long long timeout = rdtsc() + delta; - while (rdtsc() < timeout) ; -#endif + /* FIXME */ + return 0; } -/** - * Delay for a specified number of nanoseconds. - * - * @param n Number of nanoseconds to delay for. - */ -void ndelay(unsigned int n) +uint64_t timer_raw_value(void) { - _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) -{ - _delay(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(m * cpu_khz); -} - -/** - * Delay for a specified number of seconds. - * - * @param s Number of seconds to delay for. - */ -void delay(unsigned int s) -{ - _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 @@ -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) +uint64_t timer_raw_value(void) { - _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); + 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()); +}