Browse Source

[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()
tags/v0.9.4
Michael Brown 16 years ago
parent
commit
070cbebc26
2 changed files with 26 additions and 27 deletions
  1. 25
    27
      src/core/timer.c
  2. 1
    0
      src/include/gpxe/timer.h

+ 25
- 27
src/core/timer.c View File

20
 
20
 
21
 #include <stddef.h>
21
 #include <stddef.h>
22
 #include <assert.h>
22
 #include <assert.h>
23
-#include <gpxe/init.h>
24
 #include <gpxe/timer.h>
23
 #include <gpxe/timer.h>
25
 
24
 
26
 static struct timer ts_table[0]
25
 static struct timer ts_table[0]
28
 static struct timer ts_table_end[0]
27
 static struct timer ts_table_end[0]
29
 	__table_end ( struct timer, timers );
28
 	__table_end ( struct timer, timers );
30
 
29
 
31
-
32
-static struct timer *used_ts = NULL;
33
-
34
 /*
30
 /*
35
  * This function may be used in custom timer driver.
31
  * This function may be used in custom timer driver.
36
  *
32
  *
37
  * This udelay implementation works well if you've got a
33
  * This udelay implementation works well if you've got a
38
  * fast currticks().
34
  * fast currticks().
39
  */
35
  */
40
-void generic_currticks_udelay(unsigned int usecs)
41
-{
42
-	tick_t t;
43
-
44
-	t = currticks();
45
-	while (t + usecs > currticks())
46
-		; /* xxx: Relax the cpu some way. */
36
+void generic_currticks_udelay ( unsigned int usecs ) {
37
+	tick_t start;
38
+	tick_t elapsed;
39
+	
40
+	start = currticks();
41
+	do {
42
+		/* xxx: Relax the cpu some way. */
43
+		elapsed = ( currticks() - start );
44
+	} while ( elapsed < usecs );
47
 }
45
 }
48
 
46
 
47
+/**
48
+ * Identify timer source
49
+ *
50
+ * @ret timer		Timer source
51
+ */
52
+static struct timer * timer ( void ) {
53
+	static struct timer *ts = NULL;
49
 
54
 
50
-static void timer_init(void)
51
-{
52
-	struct timer *ts;
55
+	/* If we have a timer, use it */
56
+	if ( ts )
57
+		return ts;
53
 
58
 
54
-	for (ts = ts_table; ts < ts_table_end; ts++) {
55
-		if ( ts->init() == 0 ) {
56
-			used_ts = ts;
57
-			return;
58
-		}
59
+	/* Scan for a usable timer */
60
+	for ( ts = ts_table ; ts < ts_table_end ; ts++ ) {
61
+		if ( ts->init() == 0 )
62
+			return ts;
59
 	}
63
 	}
60
 
64
 
61
 	/* No timer found; we cannot continue */
65
 	/* No timer found; we cannot continue */
63
 	while ( 1 ) {};
67
 	while ( 1 ) {};
64
 }
68
 }
65
 
69
 
66
-struct init_fn ts_init_fn __init_fn ( INIT_NORMAL ) = {
67
-	.initialise = timer_init,
68
-};
69
-
70
 /**
70
 /**
71
  * Read current time
71
  * Read current time
72
  *
72
  *
74
  */
74
  */
75
 tick_t currticks ( void ) {
75
 tick_t currticks ( void ) {
76
 	tick_t ct;
76
 	tick_t ct;
77
-	assert(used_ts);
78
 
77
 
79
-	ct = used_ts->currticks();
78
+	ct = timer()->currticks();
80
 	DBG ( "currticks: %ld.%06ld seconds\n",
79
 	DBG ( "currticks: %ld.%06ld seconds\n",
81
 	      ct / USECS_IN_SEC, ct % USECS_IN_SEC );
80
 	      ct / USECS_IN_SEC, ct % USECS_IN_SEC );
82
 
81
 
89
  * @v usecs	Time to delay, in microseconds
88
  * @v usecs	Time to delay, in microseconds
90
  */
89
  */
91
 void udelay ( unsigned int usecs ) {
90
 void udelay ( unsigned int usecs ) {
92
-	assert(used_ts);
93
-	used_ts->udelay ( usecs );
91
+	timer()->udelay ( usecs );
94
 }
92
 }
95
 
93
 
96
 /**
94
 /**

+ 1
- 0
src/include/gpxe/timer.h View File

2
 #define GPXE_TIMER_H
2
 #define GPXE_TIMER_H
3
 
3
 
4
 #include <stddef.h>
4
 #include <stddef.h>
5
+#include <gpxe/tables.h>
5
 
6
 
6
 typedef unsigned long tick_t;
7
 typedef unsigned long tick_t;
7
 
8
 

Loading…
Cancel
Save