Переглянути джерело

Introduce the new timer subsystem.

	Timer subsystem initialization code in core/timer.c

	Split the BIOS and RTDSC timer drivers from i386_timer.c

	Split arch/i386/firmware/pcbios/bios.c into the RTSDC
	timer driver and arch/i386/core/nap.c

	Split the headers properly:
		include/unistd.h - delay functions to be used by the
					gPXE core and drivers.

		include/gpxe/timer.h - the fimer subsystem interface
					to be used by the timer drivers
					and currticks() to be used by
					the code gPXE subsystems.

		include/latch.h	- removed
		include/timer.h - scheduled for removal. Some driver
					are using currticks, which is
					only for core subsystems.

Signed-off-by: Alexey Zaytsev <alexey.zaytsev@gmail.com>
tags/v0.9.4
Alexey Zaytsev 16 роки тому
джерело
коміт
4006d229e5

+ 53
- 160
src/arch/i386/core/i386_timer.c Переглянути файл

@@ -1,18 +1,58 @@
1
-/* A couple of routines to implement a low-overhead timer for drivers */
2
-
3
- /*
1
+/*
2
+ * arch/i386/core/i386_timer.c
3
+ *
4
+ * Use the "System Timer 2" to implement the udelay callback in
5
+ * the BIOS timer driver. Also used to calibrate the clock rate
6
+ * in the RTDSC timer driver.
7
+ * 
4 8
  * This program is free software; you can redistribute it and/or
5 9
  * modify it under the terms of the GNU General Public License as
6 10
  * published by the Free Software Foundation; either version 2, or (at
7 11
  * your option) any later version.
8 12
  */
9 13
 
10
-#include	"timer.h"
11
-#include	"latch.h"
12
-#include	<io.h>
13
-#include	<gpxe/init.h>
14
+#include <stddef.h>
15
+#include <bits/timer2.h>
16
+#include <gpxe/timer.h>
17
+#include <io.h>
18
+
19
+/* Timers tick over at this rate */
20
+#define TIMER2_TICK_RATE	1193180U
21
+
22
+/* Parallel Peripheral Controller Port B */
23
+#define	PPC_PORTB	0x61
24
+
25
+/* Meaning of the port bits */
26
+#define	PPCB_T2OUT	0x20	/* Bit 5 */
27
+#define	PPCB_SPKR	0x02	/* Bit 1 */
28
+#define	PPCB_T2GATE	0x01	/* Bit 0 */
29
+
30
+/* Ports for the 8254 timer chip */
31
+#define	TIMER2_PORT	0x42
32
+#define	TIMER_MODE_PORT	0x43
33
+
34
+/* Meaning of the mode bits */
35
+#define	TIMER0_SEL	0x00
36
+#define	TIMER1_SEL	0x40
37
+#define	TIMER2_SEL	0x80
38
+#define	READBACK_SEL	0xC0
39
+
40
+#define	LATCH_COUNT	0x00
41
+#define	LOBYTE_ACCESS	0x10
42
+#define	HIBYTE_ACCESS	0x20
43
+#define	WORD_ACCESS	0x30
44
+
45
+#define	MODE0		0x00
46
+#define	MODE1		0x02
47
+#define	MODE2		0x04
48
+#define	MODE3		0x06
49
+#define	MODE4		0x08
50
+#define	MODE5		0x0A
14 51
 
15
-void __load_timer2(unsigned int ticks)
52
+#define	BINARY_COUNT	0x00
53
+#define	BCD_COUNT	0x01
54
+
55
+static void load_timer2(unsigned int ticks)
16 56
 {
17 57
 	/*
18 58
 	 * Now let's take care of PPC channel 2
@@ -35,162 +75,15 @@ void __load_timer2(unsigned int ticks)
35 75
 	outb(ticks >> 8, TIMER2_PORT);
36 76
 }
37 77
 
38
-static int __timer2_running(void)
78
+static int timer2_running(void)
39 79
 {
40 80
 	return ((inb(PPC_PORTB) & PPCB_T2OUT) == 0);
41 81
 }
42 82
 
43
-#if !defined(CONFIG_TSC_CURRTICKS)
44
-static void setup_timers(void)
45
-{
46
-	return;
47
-}
48
-
49
-void load_timer2(unsigned int ticks)
50
-{
51
-	return __load_timer2(ticks);
52
-}
53
-
54
-int timer2_running(void)
55
-{
56
-	return __timer2_running();
57
-}
58
-
59
-void ndelay(unsigned int nsecs)
60
-{
61
-	waiton_timer2((nsecs * CLOCK_TICK_RATE)/1000000000);
62
-}
63
-void udelay(unsigned int usecs)
64
-{
65
-	waiton_timer2((usecs * TICKS_PER_MS)/1000);
66
-}
67
-#endif /* !defined(CONFIG_TSC_CURRTICKS) */
68
-
69
-#if defined(CONFIG_TSC_CURRTICKS)
70
-
71
-#define rdtsc(low,high) \
72
-     __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high))
73
-
74
-#define rdtscll(val) \
75
-     __asm__ __volatile__ ("rdtsc" : "=A" (val))
76
-
77
-
78
-/* Number of clock ticks to time with the rtc */
79
-#define LATCH 0xFF
80
-
81
-#define LATCHES_PER_SEC ((CLOCK_TICK_RATE + (LATCH/2))/LATCH)
82
-#define TICKS_PER_LATCH ((LATCHES_PER_SEC + (TICKS_PER_SEC/2))/TICKS_PER_SEC)
83
-
84
-static void sleep_latch(void)
83
+void i386_timer2_udelay(unsigned int usecs)
85 84
 {
86
-	__load_timer2(LATCH);
87
-	while(__timer2_running());
85
+		load_timer2((usecs * TIMER2_TICK_RATE)/USECS_IN_SEC);
86
+		while (timer2_running())
87
+			;
88 88
 }
89 89
 
90
-/* ------ Calibrate the TSC ------- 
91
- * Time how long it takes to excute a loop that runs in known time.
92
- * And find the convertion needed to get to CLOCK_TICK_RATE
93
- */
94
-
95
-
96
-static unsigned long long calibrate_tsc(void)
97
-{
98
-	unsigned long startlow, starthigh;
99
-	unsigned long endlow, endhigh;
100
-	
101
-	rdtsc(startlow,starthigh);
102
-	sleep_latch();
103
-	rdtsc(endlow,endhigh);
104
-
105
-	/* 64-bit subtract - gcc just messes up with long longs */
106
-	__asm__("subl %2,%0\n\t"
107
-		"sbbl %3,%1"
108
-		:"=a" (endlow), "=d" (endhigh)
109
-		:"g" (startlow), "g" (starthigh),
110
-		"0" (endlow), "1" (endhigh));
111
-	
112
-	/* Error: ECPUTOOFAST */
113
-	if (endhigh)
114
-		goto bad_ctc;
115
-	
116
-	endlow *= TICKS_PER_LATCH;
117
-	return endlow;
118
-
119
-	/*
120
-	 * The CTC wasn't reliable: we got a hit on the very first read,
121
-	 * or the CPU was so fast/slow that the quotient wouldn't fit in
122
-	 * 32 bits..
123
-	 */
124
-bad_ctc:
125
-	printf("bad_ctc\n");
126
-	return 0;
127
-}
128
-
129
-static unsigned long clocks_per_tick;
130
-static void setup_timers(void)
131
-{
132
-	if (!clocks_per_tick) {
133
-		clocks_per_tick = calibrate_tsc();
134
-		/* Display the CPU Mhz to easily test if the calibration was bad */
135
-		printf("CPU %ld Mhz\n", (clocks_per_tick/1000 * TICKS_PER_SEC)/1000);
136
-	}
137
-}
138
-
139
-unsigned long currticks(void)
140
-{
141
-	unsigned long clocks_high, clocks_low;
142
-	unsigned long currticks;
143
-	/* Read the Time Stamp Counter */
144
-	rdtsc(clocks_low, clocks_high);
145
-
146
-	/* currticks = clocks / clocks_per_tick; */
147
-	__asm__("divl %1"
148
-		:"=a" (currticks)
149
-		:"r" (clocks_per_tick), "0" (clocks_low), "d" (clocks_high));
150
-
151
-
152
-	return currticks;
153
-}
154
-
155
-static unsigned long long timer_timeout;
156
-static int __timer_running(void)
157
-{
158
-	unsigned long long now;
159
-	rdtscll(now);
160
-	return now < timer_timeout;
161
-}
162
-
163
-void udelay(unsigned int usecs)
164
-{
165
-	unsigned long long now;
166
-	rdtscll(now);
167
-	timer_timeout = now + usecs * ((clocks_per_tick * TICKS_PER_SEC)/(1000*1000));
168
-	while(__timer_running());
169
-}
170
-void ndelay(unsigned int nsecs)
171
-{
172
-	unsigned long long now;
173
-	rdtscll(now);
174
-	timer_timeout = now + nsecs * ((clocks_per_tick * TICKS_PER_SEC)/(1000*1000*1000));
175
-	while(__timer_running());
176
-}
177
-
178
-void load_timer2(unsigned int timer2_ticks)
179
-{
180
-	unsigned long long now;
181
-	unsigned long clocks;
182
-	rdtscll(now);
183
-	clocks = timer2_ticks * ((clocks_per_tick * TICKS_PER_SEC)/CLOCK_TICK_RATE);
184
-	timer_timeout = now + clocks;
185
-}
186
-
187
-int timer2_running(void)
188
-{
189
-	return __timer_running();
190
-}
191
-
192
-#endif /* RTC_CURRTICKS */
193
-
194
-struct init_fn timer_init_fn __init_fn ( INIT_NORMAL ) = {
195
-	.initialise = setup_timers,
196
-};

+ 12
- 0
src/arch/i386/core/nap.c Переглянути файл

@@ -0,0 +1,12 @@
1
+
2
+#include <realmode.h>
3
+#include <bios.h>
4
+
5
+/**************************************************************************
6
+ * Save power by halting the CPU until the next interrupt
7
+ **************************************************************************/
8
+void cpu_nap ( void ) {
9
+	__asm__ __volatile__ ( REAL_CODE ( "sti\n\t"
10
+					   "hlt\n\t"
11
+					   "cli\n\t" ) : : );
12
+}

+ 57
- 0
src/arch/i386/drivers/timer_bios.c Переглянути файл

@@ -0,0 +1,57 @@
1
+/*
2
+ * Etherboot routines for PCBIOS firmware.
3
+ *
4
+ * Body of routines taken from old pcbios.S
5
+ */
6
+
7
+#include <gpxe/init.h>
8
+#include <gpxe/timer.h>
9
+#include <stdio.h>
10
+#include <realmode.h>
11
+#include <bios.h>
12
+#include <bits/timer2.h>
13
+
14
+/* A bit faster actually, but we don't care. */
15
+#define	TIMER2_TICKS_PER_SEC	18
16
+
17
+/*
18
+ * Use direct memory access to BIOS variables, longword 0040:006C (ticks
19
+ * today) and byte 0040:0070 (midnight crossover flag) instead of calling
20
+ * timeofday BIOS interrupt.
21
+ */
22
+
23
+static tick_t bios_currticks ( void ) {
24
+	static int days = 0;
25
+	uint32_t ticks;
26
+	uint8_t midnight;
27
+
28
+	/* Re-enable interrupts so that the timer interrupt can occur */
29
+	__asm__ __volatile__ ( REAL_CODE ( "sti\n\t"
30
+					   "nop\n\t"
31
+					   "nop\n\t"
32
+					   "cli\n\t" ) : : );
33
+
34
+	get_real ( ticks, BDA_SEG, 0x006c );
35
+	get_real ( midnight, BDA_SEG, 0x0070 );
36
+
37
+	if ( midnight ) {
38
+		midnight = 0;
39
+		put_real ( midnight, BDA_SEG, 0x0070 );
40
+		days += 0x1800b0;
41
+	}
42
+
43
+	return ( (days + ticks) * (USECS_IN_SEC / TIMER2_TICKS_PER_SEC) );
44
+}
45
+
46
+static int bios_ts_init(void)
47
+{
48
+	DBG("BIOS timer installed\n");
49
+	return 0;
50
+}
51
+
52
+struct timer bios_ts __timer ( 02 ) = {
53
+	.init = bios_ts_init,
54
+	.udelay = i386_timer2_udelay,
55
+	.currticks = bios_currticks,
56
+};
57
+

+ 90
- 0
src/arch/i386/drivers/timer_rtdsc.c Переглянути файл

@@ -0,0 +1,90 @@
1
+
2
+#include <gpxe/init.h>
3
+#include <gpxe/timer.h>
4
+#include <stdio.h>
5
+#include <bits/cpu.h>
6
+#include <bits/timer2.h>
7
+#include <io.h>
8
+
9
+
10
+#define rdtsc(low,high) \
11
+     __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high))
12
+
13
+#define rdtscll(val) \
14
+     __asm__ __volatile__ ("rdtsc" : "=A" (val))
15
+
16
+static unsigned long long calibrate_tsc(void)
17
+{
18
+	uint32_t startlow, starthigh;
19
+	uint32_t endlow, endhigh;
20
+
21
+	rdtsc(startlow,starthigh);
22
+	i386_timer2_udelay(USECS_IN_MSEC/2);
23
+	rdtsc(endlow,endhigh);
24
+
25
+	/* 64-bit subtract - gcc just messes up with long longs */
26
+	/* XXX ORLY? Check it. */
27
+	__asm__("subl %2,%0\n\t"
28
+		"sbbl %3,%1"
29
+		:"=a" (endlow), "=d" (endhigh)
30
+		:"g" (startlow), "g" (starthigh),
31
+		"0" (endlow), "1" (endhigh));
32
+
33
+	/* Error: ECPUTOOFAST */
34
+	if (endhigh)
35
+		goto bad_ctc;
36
+
37
+	endlow *= MSECS_IN_SEC*2;
38
+	return endlow;
39
+
40
+	/*
41
+	 * The CTC wasn't reliable: we got a hit on the very first read,
42
+	 * or the CPU was so fast/slow that the quotient wouldn't fit in
43
+	 * 32 bits..
44
+	 */
45
+bad_ctc:
46
+	return 0;
47
+}
48
+static uint32_t clocks_per_second = 0;
49
+
50
+static tick_t rtdsc_currticks(void)
51
+{
52
+	uint32_t clocks_high, clocks_low;
53
+	uint32_t currticks;
54
+
55
+	/* Read the Time Stamp Counter */
56
+	rdtsc(clocks_low, clocks_high);
57
+
58
+	/* currticks = clocks / clocks_per_tick; */
59
+	__asm__("divl %1"
60
+		:"=a" (currticks)
61
+		:"r" (clocks_per_second/USECS_IN_SEC), "0" (clocks_low), "d" (clocks_high));
62
+
63
+	return currticks;
64
+}
65
+
66
+static int rtdsc_ts_init(void)
67
+{
68
+
69
+	struct cpuinfo_x86 cpu_info;
70
+
71
+	get_cpuinfo(&cpu_info);
72
+	if (cpu_info.features & X86_FEATURE_TSC) {
73
+		clocks_per_second = calibrate_tsc();
74
+		if (clocks_per_second) {
75
+			DBG("RTDSC Ticksource installed. CPU running at %ld Mhz\n",
76
+				clocks_per_second/(1000*1000));
77
+			return 0;
78
+		}
79
+	}
80
+
81
+	printf("RTDSC timer not available on this machine.\n");
82
+	return 1;
83
+}
84
+
85
+struct timer rtdsc_ts __timer (01) = {
86
+	.init = rtdsc_ts_init,
87
+	.udelay = generic_currticks_udelay,
88
+	.currticks = rtdsc_currticks,
89
+};
90
+

+ 0
- 55
src/arch/i386/firmware/pcbios/bios.c Переглянути файл

@@ -1,55 +0,0 @@
1
-/* Etherboot routines for PCBIOS firmware.
2
- *
3
- * Body of routines taken from old pcbios.S
4
- */
5
-
6
-#include <stdint.h>
7
-#include <realmode.h>
8
-#include <bios.h>
9
-
10
-#define CF ( 1 << 0 )
11
-
12
-/**************************************************************************
13
-CURRTICKS - Get Time
14
-Use direct memory access to BIOS variables, longword 0040:006C (ticks
15
-today) and byte 0040:0070 (midnight crossover flag) instead of calling
16
-timeofday BIOS interrupt.
17
-**************************************************************************/
18
-#if defined(CONFIG_TSC_CURRTICKS)
19
-#undef CONFIG_BIOS_CURRTICKS
20
-#else
21
-#define CONFIG_BIOS_CURRTICKS 1
22
-#endif
23
-#if defined(CONFIG_BIOS_CURRTICKS)
24
-unsigned long currticks ( void ) {
25
-	static uint32_t days = 0;
26
-	uint32_t ticks;
27
-	uint8_t midnight;
28
-
29
-	/* Re-enable interrupts so that the timer interrupt can occur
30
-	 */
31
-	__asm__ __volatile__ ( REAL_CODE ( "sti\n\t"
32
-					   "nop\n\t"
33
-					   "nop\n\t"
34
-					   "cli\n\t" ) : : );
35
-
36
-	get_real ( ticks, BDA_SEG, 0x006c );
37
-	get_real ( midnight, BDA_SEG, 0x0070 );
38
-
39
-	if ( midnight ) {
40
-		midnight = 0;
41
-		put_real ( midnight, BDA_SEG, 0x0070 );
42
-		days += 0x1800b0;
43
-	}
44
-	return ( days + ticks );
45
-}
46
-#endif	/* CONFIG_BIOS_CURRTICKS */
47
-
48
-/**************************************************************************
49
-CPU_NAP - Save power by halting the CPU until the next interrupt
50
-**************************************************************************/
51
-void cpu_nap ( void ) {
52
-	__asm__ __volatile__ ( REAL_CODE ( "sti\n\t"
53
-					   "hlt\n\t"
54
-					   "cli\n\t" ) : : );
55
-}

+ 8
- 0
src/arch/i386/include/bits/timer2.h Переглянути файл

@@ -0,0 +1,8 @@
1
+#ifndef BITS_TIMER2_H
2
+#define BITS_TIMER2_H
3
+
4
+#include <stddef.h>
5
+
6
+void i386_timer2_udelay(unsigned int usecs);
7
+
8
+#endif

+ 4
- 1
src/config.h Переглянути файл

@@ -18,11 +18,14 @@
18 18
  */
19 19
 
20 20
 #define	CONSOLE_FIRMWARE	/* Default BIOS console */
21
-#undef	CONSOLE_SERIAL		/* Serial port */
21
+#define	CONSOLE_SERIAL		/* Serial port */
22 22
 #undef	CONSOLE_DIRECT_VGA	/* Direct access to VGA card */
23 23
 #undef	CONSOLE_BTEXT		/* Who knows what this does? */
24 24
 #undef	CONSOLE_PC_KBD		/* Direct access to PC keyboard */
25 25
 
26
+#define TIMER_BIOS
27
+#define TIMER_RTDSC
28
+
26 29
 /* @END general.h */
27 30
 
28 31
 /* @BEGIN serial.h

+ 11
- 0
src/core/config.c Переглянути файл

@@ -74,6 +74,17 @@ REQUIRE_OBJECT ( pc_kbd );
74 74
 REQUIRE_OBJECT ( syslog );
75 75
 #endif
76 76
 
77
+/*
78
+ * Timers
79
+ */
80
+
81
+#ifdef TIMER_BIOS
82
+REQUIRE_OBJECT ( timer_bios );
83
+#endif
84
+
85
+#ifdef TIMER_RTDSC
86
+REQUIRE_OBJECT ( timer_rtdsc );
87
+#endif
77 88
 /*
78 89
  * Drag in all requested protocols
79 90
  *

+ 0
- 12
src/core/misc.c Переглянути файл

@@ -7,18 +7,6 @@ MISC Support Routines
7 7
 #include <latch.h>
8 8
 #include <gpxe/in.h>
9 9
 
10
-/**************************************************************************
11
-SLEEP
12
-**************************************************************************/
13
-unsigned int sleep(unsigned int secs)
14
-{
15
-	unsigned long tmo;
16
-
17
-	for (tmo = currticks()+secs*TICKS_PER_SEC; currticks() < tmo; ) {
18
-	}
19
-	return 0;
20
-}
21
-
22 10
 /**************************************************************************
23 11
 INET_ATON - Convert an ascii x.x.x.x to binary form
24 12
 **************************************************************************/

+ 92
- 15
src/core/timer.c Переглянути файл

@@ -1,27 +1,104 @@
1
-/* A couple of routines to implement a low-overhead timer for drivers */
2
-
3
- /*
1
+/*
2
+ * core/timer.c
3
+ *
4
+ * Copyright (C) 2007 Alexey Zaytsev <alexey.zaytsev@gmail.com>
5
+ *
4 6
  * This program is free software; you can redistribute it and/or
5 7
  * modify it under the terms of the GNU General Public License as
6
- * published by the Free Software Foundation; either version 2, or (at
7
- * your option) any later version.
8
+ * published by the Free Software Foundation; either version 2 of the
9
+ * License, or any later version.
10
+ *
11
+ * This program is distributed in the hope that it will be useful, but
12
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
+ * General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU General Public License
17
+ * along with this program; if not, write to the Free Software
18
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
8 19
  */
9 20
 
10
-#include	"timer.h"
21
+#include <stddef.h>
22
+#include <assert.h>
23
+#include <gpxe/init.h>
24
+#include <gpxe/timer.h>
25
+#include <stdio.h>
11 26
 
12
-/* Machine Independant timer helper functions */
27
+static struct timer ts_table[0]
28
+	__table_start ( struct timer, timers );
29
+static struct timer ts_table_end[0]
30
+	__table_end ( struct timer, timers );
13 31
 
14
-void mdelay(unsigned int msecs)
32
+
33
+static struct timer *used_ts = NULL;
34
+
35
+/*
36
+ * This function may be used in custom timer driver.
37
+ *
38
+ * This udelay implementation works well if you've got a
39
+ * fast currticks().
40
+ */
41
+void generic_currticks_udelay(unsigned int usecs)
15 42
 {
16
-	unsigned int i;
17
-	for(i = 0; i < msecs; i++) {
18
-		udelay(1000);
19
-	}
43
+	tick_t t;
44
+
45
+	t = currticks();
46
+	while (t + usecs > currticks())
47
+		; /* xxx: Relax the cpu some way. */
20 48
 }
21 49
 
22
-void waiton_timer2(unsigned int ticks)
50
+
51
+static void timer_init(void)
23 52
 {
24
-	load_timer2(ticks);
25
-	while(timer2_running()) {
53
+	struct timer *ts;
54
+
55
+	for (ts = ts_table; ts < ts_table_end; ts++) {
56
+		if (ts->init && !ts->init()) {
57
+			used_ts = ts;
58
+			break;
59
+		}
60
+	}
61
+
62
+	if (!used_ts) {
63
+		printf("No timer available. This should never happen. Expect gPXE to die soon.\n");
64
+		/* Panic */
26 65
 	}
66
+
27 67
 }
68
+
69
+struct init_fn ts_init_fn __init_fn ( INIT_NORMAL ) = {
70
+	.initialise = timer_init,
71
+};
72
+
73
+/* Functions for public use. */
74
+
75
+tick_t currticks(void)
76
+{
77
+	tick_t ct;
78
+	assert(used_ts);
79
+
80
+	ct = used_ts->currticks();
81
+	DBG("currticks: %ld seconds and %06ld microseconds\n", ct/USECS_IN_SEC, ct%USECS_IN_SEC);
82
+
83
+	return ct;
84
+}
85
+
86
+void udelay(unsigned int usecs)
87
+{
88
+	used_ts->udelay(usecs);
89
+}
90
+
91
+void mdelay(unsigned int msecs)
92
+{
93
+	while(msecs--)
94
+		used_ts->udelay(USECS_IN_MSEC);
95
+}
96
+
97
+unsigned int sleep(unsigned int secs)
98
+{
99
+	while (secs--)
100
+		mdelay(MSECS_IN_SEC);
101
+
102
+	return 0;
103
+}
104
+

+ 32
- 0
src/include/gpxe/timer.h Переглянути файл

@@ -0,0 +1,32 @@
1
+#ifndef	GPXE_TIMER_H
2
+#define GPXE_TIMER_H
3
+
4
+#include <stddef.h>
5
+
6
+typedef uint32_t tick_t;
7
+
8
+#define MSECS_IN_SEC (1000)
9
+#define USECS_IN_SEC (1000*1000)
10
+#define USECS_IN_MSEC (1000)
11
+
12
+#define	TICKS_PER_SEC	USECS_IN_SEC
13
+
14
+tick_t currticks(void);
15
+
16
+void generic_currticks_udelay(unsigned int usecs);
17
+
18
+struct timer {
19
+	/* Returns zero on successful initialisation. */
20
+	int (*init) (void);
21
+
22
+	/* Return the current time, int mictoseconds since the beginning. */
23
+	tick_t (*currticks) (void);
24
+
25
+	/* Sleep for a few useconds. */
26
+	void (*udelay) (unsigned int useconds);
27
+};
28
+
29
+#define __timer(order) __table (struct timer, timers, order)
30
+
31
+#endif	/* GPXE_TIMER_H */
32
+

+ 18
- 52
src/include/timer.h Переглянути файл

@@ -1,61 +1,27 @@
1
-/* Defines for routines to implement a low-overhead timer for drivers */
2
-
3
- /*
4
- * This program is free software; you can redistribute it and/or
5
- * modify it under the terms of the GNU General Public License as
6
- * published by the Free Software Foundation; either version 2, or (at
7
- * your option) any later version.
8
- */
9
-
10
-#ifndef	TIMER_H
1
+#ifndef TIMER_H
11 2
 #define TIMER_H
12 3
 
13
-/* Ports for the 8254 timer chip */
14
-#define	TIMER2_PORT	0x42
15
-#define	TIMER_MODE_PORT	0x43
16
-
17
-/* Meaning of the mode bits */
18
-#define	TIMER0_SEL	0x00
19
-#define	TIMER1_SEL	0x40
20
-#define	TIMER2_SEL	0x80
21
-#define	READBACK_SEL	0xC0
22
-
23
-#define	LATCH_COUNT	0x00
24
-#define	LOBYTE_ACCESS	0x10
25
-#define	HIBYTE_ACCESS	0x20
26
-#define	WORD_ACCESS	0x30
27
-
28
-#define	MODE0		0x00
29
-#define	MODE1		0x02
30
-#define	MODE2		0x04
31
-#define	MODE3		0x06
32
-#define	MODE4		0x08
33
-#define	MODE5		0x0A
34
-
35
-#define	BINARY_COUNT	0x00
36
-#define	BCD_COUNT	0x01
4
+/*
5
+ * This file should be removed as soon as there are no
6
+ * currticks() abusers.
7
+ */
37 8
 
38
-/* Timers tick over at this rate */
39
-#define CLOCK_TICK_RATE	1193180U
40
-#define	TICKS_PER_MS	(CLOCK_TICK_RATE/1000)
9
+#include <stddef.h>
10
+/*
11
+#warning Please fix me. I'm abusing the deprecated include/timer.h
12
+*/
13
+#include <unistd.h>
41 14
 
42
-/* Parallel Peripheral Controller Port B */
43
-#define	PPC_PORTB	0x61
15
+/* Duplicates include/gpxe/timer.h */
16
+typedef uint32_t tick_t;
44 17
 
45
-/* Meaning of the port bits */
46
-#define	PPCB_T2OUT	0x20	/* Bit 5 */
47
-#define	PPCB_SPKR	0x02	/* Bit 1 */
48
-#define	PPCB_T2GATE	0x01	/* Bit 0 */
18
+#define MSECS_IN_SEC (1000)
19
+#define USECS_IN_SEC (1000*1000)
20
+#define USECS_IN_MSEC (1000)
49 21
 
50
-/* Ticks must be between 0 and 65535 (0 == 65536)
51
-   because it is a 16 bit counter */
52
-extern void load_timer2(unsigned int ticks);
53
-extern inline int timer2_running(void);
54
-extern void waiton_timer2(unsigned int ticks);
22
+#define	TICKS_PER_SEC USECS_IN_SEC
55 23
 
56
-extern void ndelay(unsigned int nsecs);
57
-extern void udelay(unsigned int usecs);
58
-extern void mdelay(unsigned int msecs);
24
+tick_t currticks(void);
59 25
 
26
+#endif
60 27
 
61
-#endif	/* TIMER_H */

+ 7
- 1
src/include/unistd.h Переглянути файл

@@ -4,7 +4,7 @@
4 4
 #include <stddef.h>
5 5
 #include <stdarg.h>
6 6
 
7
-extern unsigned int sleep ( unsigned int seconds );
7
+unsigned int sleep ( unsigned int seconds );
8 8
 extern int execv ( const char *command, char * const argv[] );
9 9
 
10 10
 /**
@@ -22,4 +22,10 @@ extern int execv ( const char *command, char * const argv[] );
22 22
 		rc;							\
23 23
 	} )
24 24
 
25
+void udelay(unsigned int usecs);
26
+void mdelay(unsigned int msecs);
27
+
28
+#define usleep(x) udelay(x)
29
+
30
+
25 31
 #endif /* _UNISTD_H */

Завантаження…
Відмінити
Зберегти