Deleted Added
full compact
tsc.c (1407) tsc.c (1442)
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * William Jolitz and Don Ahn.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 20 unchanged lines hidden (view full) ---

29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 *
36 * from: @(#)clock.c 7.2 (Berkeley) 5/12/91
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * William Jolitz and Don Ahn.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 20 unchanged lines hidden (view full) ---

29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 *
36 * from: @(#)clock.c 7.2 (Berkeley) 5/12/91
37 * $Id: clock.c,v 1.7 1994/04/21 14:19:16 sos Exp $
37 * $Id: clock.c,v 1.6 1994/02/06 22:48:13 davidg Exp $
38 */
39
40/*
41 * Primitive clock interrupt routines.
42 */
43#include "param.h"
44#include "systm.h"
45#include "time.h"

--- 8 unchanged lines hidden (view full) ---

54/* X-tals being what they are, it's nice to be able to fudge this one... */
55/* Note, the name changed here from XTALSPEED to TIMER_FREQ rgrimes 4/26/93 */
56#ifndef TIMER_FREQ
57#define TIMER_FREQ 1193182 /* XXX - should be in isa.h */
58#endif
59#define TIMER_DIV(x) ((TIMER_FREQ+(x)/2)/(x))
60
61void hardclock();
38 */
39
40/*
41 * Primitive clock interrupt routines.
42 */
43#include "param.h"
44#include "systm.h"
45#include "time.h"

--- 8 unchanged lines hidden (view full) ---

54/* X-tals being what they are, it's nice to be able to fudge this one... */
55/* Note, the name changed here from XTALSPEED to TIMER_FREQ rgrimes 4/26/93 */
56#ifndef TIMER_FREQ
57#define TIMER_FREQ 1193182 /* XXX - should be in isa.h */
58#endif
59#define TIMER_DIV(x) ((TIMER_FREQ+(x)/2)/(x))
60
61void hardclock();
62static void findcpuspeed(void);
62static int beeping;
63int timer0_divisor = TIMER_DIV(100); /* XXX should be hz */
64u_int timer0_prescale;
65static char timer0_state = 0, timer2_state = 0;
66static char timer0_reprogram = 0;
67static void (*timer_func)() = hardclock;
68static void (*new_function)();
69static u_int new_rate;
70static u_int hardclock_divisor;
63
71
64static char timer0_in_use = 0, timer2_in_use = 0;
65static int timer0_rate = 100; /* XXX should be hz */
66static void (*timer_func)() = hardclock;
67static unsigned int prescale = 0;
68static unsigned int hardclock_prescale;
69static int beeping;
70unsigned int delaycount; /* calibrated loop variable (1 millisecond) */
71
72
72
73void
74timerintr(struct intrframe frame)
75{
76 timer_func(frame);
73void
74timerintr(struct intrframe frame)
75{
76 timer_func(frame);
77 if (timer0_in_use)
78 if (prescale++ >= hardclock_prescale) {
77 switch (timer0_state) {
78 case 0:
79 break;
80 case 1:
81 if ((timer0_prescale+=timer0_divisor) >= hardclock_divisor) {
79 hardclock(frame);
82 hardclock(frame);
80 prescale = 0;
83 timer0_prescale = 0;
81 }
84 }
85 break;
86 case 2:
87 disable_intr();
88 outb(TIMER_MODE, TIMER_SEL0|TIMER_RATEGEN|TIMER_16BIT);
89 outb(TIMER_CNTR0, TIMER_DIV(new_rate)%256);
90 outb(TIMER_CNTR0, TIMER_DIV(new_rate)/256);
91 enable_intr();
92 timer0_divisor = TIMER_DIV(new_rate);
93 timer0_prescale = 0;
94 timer_func = new_function;
95 timer0_state = 1;
96 break;
97 case 3:
98 if ((timer0_prescale+=timer0_divisor) >= hardclock_divisor) {
99 hardclock(frame);
100 disable_intr();
101 outb(TIMER_MODE, TIMER_SEL0|TIMER_RATEGEN|TIMER_16BIT);
102 outb(TIMER_CNTR0, TIMER_DIV(hz)%256);
103 outb(TIMER_CNTR0, TIMER_DIV(hz)/256);
104 enable_intr();
105 timer0_divisor = TIMER_DIV(hz);
106 timer0_prescale = 0;
107 timer_func = hardclock;;
108 timer0_state = 0;
109 }
110 break;
111 }
82}
83
84
85int
86acquire_timer0(int rate, void (*function)() )
87{
112}
113
114
115int
116acquire_timer0(int rate, void (*function)() )
117{
88#ifndef INACCURATE_MICROTIME_IS_OK
89 return -1;
90#else
91 if (timer0_in_use) /* XXX || (rate < 20000 && rate % hz)) */
118 if (timer0_state || !function)
92 return -1;
119 return -1;
93 timer0_in_use = 1;
94 timer0_rate = rate;
95 prescale = 0;
96 hardclock_prescale = rate/hz;
97 outb(TIMER_MODE, TIMER_SEL0|TIMER_RATEGEN|TIMER_16BIT);
98 outb(TIMER_CNTR0, TIMER_DIV(rate)%256);
99 outb(TIMER_CNTR0, TIMER_DIV(rate)/256);
100 if (function)
101 timer_func = function;
120
121 new_function = function;
122 new_rate = rate;
123 timer0_state = 2;
102 return 0;
124 return 0;
103#endif
104}
105
106
107int
108acquire_timer2(int mode)
109{
125}
126
127
128int
129acquire_timer2(int mode)
130{
110 if (timer2_in_use)
131 if (timer2_state)
111 return -1;
132 return -1;
112 timer2_in_use = 1;
133 timer2_state = 1;
113 outb(TIMER_MODE, TIMER_SEL2 | (mode &0x3f));
114 return 0;
115}
116
117
118int
119release_timer0()
120{
134 outb(TIMER_MODE, TIMER_SEL2 | (mode &0x3f));
135 return 0;
136}
137
138
139int
140release_timer0()
141{
121 if (!timer0_in_use)
142 if (!timer0_state)
122 return -1;
143 return -1;
123 timer0_in_use = 0;
124 timer0_rate = hz;
125 outb(TIMER_MODE, TIMER_SEL0|TIMER_RATEGEN|TIMER_16BIT);
126 outb(TIMER_CNTR0, TIMER_DIV(hz)%256);
127 outb(TIMER_CNTR0, TIMER_DIV(hz)/256);
128 timer_func = hardclock;
144 timer0_state = 3;
129 return 0;
130}
131
132
133int
134release_timer2()
135{
145 return 0;
146}
147
148
149int
150release_timer2()
151{
136 if (!timer2_in_use)
152 if (!timer2_state)
137 return -1;
153 return -1;
138 timer2_in_use = 0;
154 timer2_state = 0;
139 outb(TIMER_MODE, TIMER_SEL2|TIMER_SQWAVE|TIMER_16BIT);
140 return 0;
141}
142
143
144static int
145getit()
146{
147 int high, low;
148
149 disable_intr();
155 outb(TIMER_MODE, TIMER_SEL2|TIMER_SQWAVE|TIMER_16BIT);
156 return 0;
157}
158
159
160static int
161getit()
162{
163 int high, low;
164
165 disable_intr();
150
151 /* select timer0 and latch counter value */
152 outb(TIMER_MODE, TIMER_SEL0);
153 low = inb(TIMER_CNTR0);
154 high = inb(TIMER_CNTR0);
155 enable_intr();
156 return ((high << 8) | low);
157}
158

--- 37 unchanged lines hidden (view full) ---

196 */
197 sec = n / 1000000;
198 usec = n - sec * 1000000;
199 ticks_left = sec * TIMER_FREQ
200 + usec * (TIMER_FREQ / 1000000)
201 + usec * ((TIMER_FREQ % 1000000) / 1000) / 1000
202 + usec * (TIMER_FREQ % 1000) / 1000000;
203
166 /* select timer0 and latch counter value */
167 outb(TIMER_MODE, TIMER_SEL0);
168 low = inb(TIMER_CNTR0);
169 high = inb(TIMER_CNTR0);
170 enable_intr();
171 return ((high << 8) | low);
172}
173

--- 37 unchanged lines hidden (view full) ---

211 */
212 sec = n / 1000000;
213 usec = n - sec * 1000000;
214 ticks_left = sec * TIMER_FREQ
215 + usec * (TIMER_FREQ / 1000000)
216 + usec * ((TIMER_FREQ % 1000000) / 1000) / 1000
217 + usec * (TIMER_FREQ % 1000) / 1000000;
218
204 counter_limit = TIMER_FREQ/timer0_rate;
205 while (ticks_left > 0) {
206 tick = getit(0, 0);
207#ifdef DELAYDEBUG
208 ++getit_calls;
209#endif
210 if (tick > prev_tick)
219 while (ticks_left > 0) {
220 tick = getit(0, 0);
221#ifdef DELAYDEBUG
222 ++getit_calls;
223#endif
224 if (tick > prev_tick)
211 ticks_left -= prev_tick - (tick - counter_limit);
225 ticks_left -= prev_tick - (tick - timer0_divisor);
212 else
213 ticks_left -= prev_tick - tick;
214 prev_tick = tick;
215 }
216#ifdef DELAYDEBUG
217 if (state == 1)
218 printf(" %d calls to getit() at %d usec each\n",
219 getit_calls, (n + 5) / getit_calls);
220#endif
221}
222
223
224static void
226 else
227 ticks_left -= prev_tick - tick;
228 prev_tick = tick;
229 }
230#ifdef DELAYDEBUG
231 if (state == 1)
232 printf(" %d calls to getit() at %d usec each\n",
233 getit_calls, (n + 5) / getit_calls);
234#endif
235}
236
237
238static void
225sysbeepstop() /* SOS XXX dummy is not needed */
239sysbeepstop()
226{
227 outb(IO_PPI, inb(IO_PPI)&0xFC); /* disable counter2 output to speaker */
228 release_timer2();
229 beeping = 0;
230}
231
232
233int
234sysbeep(int pitch, int period)
235{
236
237 if (acquire_timer2(TIMER_SQWAVE|TIMER_16BIT))
238 return -1;
240{
241 outb(IO_PPI, inb(IO_PPI)&0xFC); /* disable counter2 output to speaker */
242 release_timer2();
243 beeping = 0;
244}
245
246
247int
248sysbeep(int pitch, int period)
249{
250
251 if (acquire_timer2(TIMER_SQWAVE|TIMER_16BIT))
252 return -1;
253 disable_intr();
239 outb(TIMER_CNTR2, pitch);
240 outb(TIMER_CNTR2, (pitch>>8));
254 outb(TIMER_CNTR2, pitch);
255 outb(TIMER_CNTR2, (pitch>>8));
256 enable_intr();
241 if (!beeping) {
242 outb(IO_PPI, inb(IO_PPI) | 3); /* enable counter2 output to speaker */
243 beeping = period;
244 timeout(sysbeepstop, 0, period);
245 }
246 return 0;
247}
248
249
250void
251startrtclock()
252{
253 int s;
254
257 if (!beeping) {
258 outb(IO_PPI, inb(IO_PPI) | 3); /* enable counter2 output to speaker */
259 beeping = period;
260 timeout(sysbeepstop, 0, period);
261 }
262 return 0;
263}
264
265
266void
267startrtclock()
268{
269 int s;
270
255 findcpuspeed(); /* use the clock (while it's free)
256 to find the cpu speed */
257 /* initialize 8253 clock */
258 outb(TIMER_MODE, TIMER_SEL0|TIMER_RATEGEN|TIMER_16BIT);
259
260 /* Correct rounding will buy us a better precision in timekeeping */
261 outb (IO_TIMER1, TIMER_DIV(hz)%256);
262 outb (IO_TIMER1, TIMER_DIV(hz)/256);
271 /* initialize 8253 clock */
272 outb(TIMER_MODE, TIMER_SEL0|TIMER_RATEGEN|TIMER_16BIT);
273
274 /* Correct rounding will buy us a better precision in timekeeping */
275 outb (IO_TIMER1, TIMER_DIV(hz)%256);
276 outb (IO_TIMER1, TIMER_DIV(hz)/256);
263 timer0_rate = hz;
277 timer0_divisor = hardclock_divisor = TIMER_DIV(hz);
264
265 /* initialize brain-dead battery powered clock */
266 outb (IO_RTC, RTC_STATUSA);
267 outb (IO_RTC+1, 0x26);
268 outb (IO_RTC, RTC_STATUSB);
269 outb (IO_RTC+1, 2);
270
271 outb (IO_RTC, RTC_DIAG);
272 if (s = inb (IO_RTC+1))
273 printf("RTC BIOS diagnostic error %b\n", s, RTCDG_BITS);
274}
275
276
278
279 /* initialize brain-dead battery powered clock */
280 outb (IO_RTC, RTC_STATUSA);
281 outb (IO_RTC+1, 0x26);
282 outb (IO_RTC, RTC_STATUSB);
283 outb (IO_RTC+1, 2);
284
285 outb (IO_RTC, RTC_DIAG);
286 if (s = inb (IO_RTC+1))
287 printf("RTC BIOS diagnostic error %b\n", s, RTCDG_BITS);
288}
289
290
277#define FIRST_GUESS 0x2000
278static void
279findcpuspeed()
280{
281 unsigned char low;
282 unsigned int remainder;
283
284 /* Put counter in count down mode */
285 outb(TIMER_MODE, TIMER_16BIT|TIMER_RATEGEN);
286 outb(IO_TIMER1, 0xff);
287 outb(IO_TIMER1, 0xff);
288 delaycount = FIRST_GUESS;
289 spinwait(1);
290 /* Read the value left in the counter */
291 low = inb(IO_TIMER1); /* least siginifcant */
292 remainder = inb(IO_TIMER1); /* most significant */
293 remainder = (remainder<<8) + low ;
294 /* Formula for delaycount is :
295 * (loopcount * timer clock speed)/ (counter ticks * 1000)
296 */
297 delaycount = (FIRST_GUESS * (TIMER_FREQ/1000)) / (0xffff-remainder);
298}
299
300
301/* convert 2 digit BCD number */
302int
303bcd(int i)
304{
305 return ((i/16)*10 + (i%16));
306}
307
308

--- 54 unchanged lines hidden (view full) ---

363 /* ready for a read? */
364 while ((sa&RTCSA_TUP) == RTCSA_TUP)
365 sa = rtcin(RTC_STATUSA);
366
367 sec = bcd(rtcin(RTC_YEAR)) + 1900;
368 if (sec < 1970)
369 sec += 100;
370
291/* convert 2 digit BCD number */
292int
293bcd(int i)
294{
295 return ((i/16)*10 + (i%16));
296}
297
298

--- 54 unchanged lines hidden (view full) ---

353 /* ready for a read? */
354 while ((sa&RTCSA_TUP) == RTCSA_TUP)
355 sa = rtcin(RTC_STATUSA);
356
357 sec = bcd(rtcin(RTC_YEAR)) + 1900;
358 if (sec < 1970)
359 sec += 100;
360
371 leap = !(sec % 4); sec = ytos(sec); /* year */
361 leap = !(sec % 4); sec = ytos(sec); /* year */
372 yd = mtos(bcd(rtcin(RTC_MONTH)),leap); sec+=yd; /* month */
373 t = (bcd(rtcin(RTC_DAY))-1) * 24*60*60; sec+=t; yd+=t; /* date */
374 day_week = rtcin(RTC_WDAY); /* day */
375 sec += bcd(rtcin(RTC_HRS)) * 60*60; /* hour */
376 sec += bcd(rtcin(RTC_MIN)) * 60; /* minutes */
377 sec += bcd(rtcin(RTC_SEC)); /* seconds */
378 sec += tz.tz_minuteswest * 60;
379 time.tv_sec = sec;

--- 61 unchanged lines hidden ---
362 yd = mtos(bcd(rtcin(RTC_MONTH)),leap); sec+=yd; /* month */
363 t = (bcd(rtcin(RTC_DAY))-1) * 24*60*60; sec+=t; yd+=t; /* date */
364 day_week = rtcin(RTC_WDAY); /* day */
365 sec += bcd(rtcin(RTC_HRS)) * 60*60; /* hour */
366 sec += bcd(rtcin(RTC_MIN)) * 60; /* minutes */
367 sec += bcd(rtcin(RTC_SEC)); /* seconds */
368 sec += tz.tz_minuteswest * 60;
369 time.tv_sec = sec;

--- 61 unchanged lines hidden ---