diff options
author | Gabe Black <gabeblack@google.com> | 2013-02-22 16:38:53 -0800 |
---|---|---|
committer | Ronald G. Minnich <rminnich@gmail.com> | 2013-03-14 04:53:33 +0100 |
commit | 5c0b7abe786d7b4370ed1dd7ef323a3091d9620c (patch) | |
tree | cbd054ae9d0b25a024bead99d1c61bf287563b0e /payloads/libpayload/libc | |
parent | 6a0b3611c5b057907aabe2a1c05302440da9bc19 (diff) |
libpayload: Generalize and redistribute timekeeping code
The timekeeping code in libpayload was dependent on rdtsc, and when it was
split up by arch, that code was duplicated even though it was mostly the same.
This change factors out actually reading the count from the timer and the
speed of the timer and puts the definitions of ndelay, udelay, mdelay and
delay into generic code. Then, in x86, the timer_hz and timer_get_raw_value
functions which used to be in depthcharge were moved over to libpayload's
arch/x86/timer.c. In ARM where there isn't a single, canonical timer, those
functions are omitted with the intention that they'll be implemented by a
specific timer driver chosen elsewhere.
Change-Id: I9c919bed712ace941f417c1d58679d667b2d8269
Signed-off-by: Gabe Black <gabeblack@google.com>
Reviewed-on: http://review.coreboot.org/2717
Tested-by: build bot (Jenkins)
Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
Diffstat (limited to 'payloads/libpayload/libc')
-rw-r--r-- | payloads/libpayload/libc/time.c | 72 |
1 files changed, 58 insertions, 14 deletions
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()); +} |