summaryrefslogtreecommitdiffstats
path: root/src/core/timer.c
diff options
context:
space:
mode:
authorMichael Brown2008-03-18 16:23:10 +0100
committerMichael Brown2008-03-18 16:23:10 +0100
commit070cbebc26781c569e180a4a03107be2af94e58b (patch)
tree7f402cabc56e0c5ef57ee2c7b1f662a2c688a53b /src/core/timer.c
parent[Timers] Miscellaneous timer system fixes (diff)
downloadipxe-070cbebc26781c569e180a4a03107be2af94e58b.tar.gz
ipxe-070cbebc26781c569e180a4a03107be2af94e58b.tar.xz
ipxe-070cbebc26781c569e180a4a03107be2af94e58b.zip
[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()
Diffstat (limited to 'src/core/timer.c')
-rw-r--r--src/core/timer.c52
1 files changed, 25 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 <stddef.h>
#include <assert.h>
-#include <gpxe/init.h>
#include <gpxe/timer.h>
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 );
}
/**