From 070cbebc26781c569e180a4a03107be2af94e58b Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Tue, 18 Mar 2008 15:23:10 +0000 Subject: [PATCH] [Timers] Initialise timers on first use Timers are sometimes required before the call to initialise(), so we cannot rely on initialise() to set up the timers before use. Also fix a potential integer overflow issue in generic_currticks_udelay() --- src/core/timer.c | 52 +++++++++++++++++++--------------------- src/include/gpxe/timer.h | 1 + 2 files changed, 26 insertions(+), 27 deletions(-) diff --git a/src/core/timer.c b/src/core/timer.c index ef80c044..4e047ea7 100644 --- a/src/core/timer.c +++ b/src/core/timer.c @@ -20,7 +20,6 @@ #include #include -#include #include static struct timer ts_table[0] @@ -28,34 +27,39 @@ static struct timer ts_table[0] static struct timer ts_table_end[0] __table_end ( struct timer, timers ); - -static struct timer *used_ts = NULL; - /* * This function may be used in custom timer driver. * * This udelay implementation works well if you've got a * fast currticks(). */ -void generic_currticks_udelay(unsigned int usecs) -{ - tick_t t; - - t = currticks(); - while (t + usecs > currticks()) - ; /* xxx: Relax the cpu some way. */ +void generic_currticks_udelay ( unsigned int usecs ) { + tick_t start; + tick_t elapsed; + + start = currticks(); + do { + /* xxx: Relax the cpu some way. */ + elapsed = ( currticks() - start ); + } while ( elapsed < usecs ); } +/** + * Identify timer source + * + * @ret timer Timer source + */ +static struct timer * timer ( void ) { + static struct timer *ts = NULL; -static void timer_init(void) -{ - struct timer *ts; + /* If we have a timer, use it */ + if ( ts ) + return ts; - for (ts = ts_table; ts < ts_table_end; ts++) { - if ( ts->init() == 0 ) { - used_ts = ts; - return; - } + /* Scan for a usable timer */ + for ( ts = ts_table ; ts < ts_table_end ; ts++ ) { + if ( ts->init() == 0 ) + return ts; } /* No timer found; we cannot continue */ @@ -63,10 +67,6 @@ static void timer_init(void) while ( 1 ) {}; } -struct init_fn ts_init_fn __init_fn ( INIT_NORMAL ) = { - .initialise = timer_init, -}; - /** * Read current time * @@ -74,9 +74,8 @@ struct init_fn ts_init_fn __init_fn ( INIT_NORMAL ) = { */ tick_t currticks ( void ) { tick_t ct; - assert(used_ts); - ct = used_ts->currticks(); + ct = timer()->currticks(); DBG ( "currticks: %ld.%06ld seconds\n", ct / USECS_IN_SEC, ct % USECS_IN_SEC ); @@ -89,8 +88,7 @@ tick_t currticks ( void ) { * @v usecs Time to delay, in microseconds */ void udelay ( unsigned int usecs ) { - assert(used_ts); - used_ts->udelay ( usecs ); + timer()->udelay ( usecs ); } /** diff --git a/src/include/gpxe/timer.h b/src/include/gpxe/timer.h index ecd30001..b7057225 100644 --- a/src/include/gpxe/timer.h +++ b/src/include/gpxe/timer.h @@ -2,6 +2,7 @@ #define GPXE_TIMER_H #include +#include typedef unsigned long tick_t;