|
|
1.1 root 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
9: * modification, are permitted provided that the following conditions
10: * are met:
11: * 1. Redistributions of source code must retain the above copyright
12: * notice, this list of conditions and the following disclaimer.
13: * 2. Redistributions in binary form must reproduce the above copyright
14: * notice, this list of conditions and the following disclaimer in the
15: * documentation and/or other materials provided with the distribution.
16: * 3. All advertising materials mentioning features or use of this software
17: * must display the following acknowledgement:
18: * This product includes software developed by the University of
19: * California, Berkeley and its contributors.
20: * 4. Neither the name of the University nor the names of its contributors
21: * may be used to endorse or promote products derived from this software
22: * without specific prior written permission.
23: *
24: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
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: * @(#)clock.c 7.2 (Berkeley) 5/12/91
1.1.1.2 ! root 37: *
! 38: * PATCHES MAGIC LEVEL PATCH THAT GOT US HERE
! 39: * -------------------- ----- ----------------------
! 40: * CURRENT PATCH LEVEL: 3 00082
! 41: * -------------------- ----- ----------------------
! 42: *
! 43: * 14 Aug 92 Arne Henrik Juul Added code in the kernel to
! 44: * allow for DST in the BIOS.
! 45: * 17 Jan 93 Bruce Evans Fixed leap year and second
! 46: * calculations
! 47: * 01 Feb 93 Julian Elischer Added code to for the cpu
! 48: * speed independent spinwait()
! 49: * function, (used by scsi and others)
1.1 root 50: */
51:
52: /*
53: * Primitive clock interrupt routines.
54: */
55: #include "param.h"
1.1.1.2 ! root 56: #include "systm.h"
1.1 root 57: #include "time.h"
58: #include "kernel.h"
59: #include "machine/segments.h"
60: #include "i386/isa/icu.h"
61: #include "i386/isa/isa.h"
62: #include "i386/isa/rtc.h"
1.1.1.2 ! root 63: #include "i386/isa/timerreg.h"
1.1 root 64:
65: #define DAYST 119
66: #define DAYEN 303
1.1.1.2 ! root 67: #define XTALSPEED 1193182
1.1 root 68:
69: startrtclock() {
70: int s;
71:
1.1.1.2 ! root 72: findcpuspeed(); /* use the clock (while it's free)
! 73: to find the cpu speed */
1.1 root 74: /* initialize 8253 clock */
1.1.1.2 ! root 75: outb(TIMER_MODE, TIMER_SEL0|TIMER_RATEGEN|TIMER_16BIT);
! 76: outb (IO_TIMER1, XTALSPEED/hz);
! 77: outb (IO_TIMER1, (XTALSPEED/hz)/256);
1.1 root 78:
79: /* initialize brain-dead battery powered clock */
80: outb (IO_RTC, RTC_STATUSA);
81: outb (IO_RTC+1, 0x26);
82: outb (IO_RTC, RTC_STATUSB);
83: outb (IO_RTC+1, 2);
84:
85: outb (IO_RTC, RTC_DIAG);
86: if (s = inb (IO_RTC+1))
87: printf("RTC BIOS diagnostic error %b\n", s, RTCDG_BITS);
88: outb (IO_RTC, RTC_DIAG);
89: outb (IO_RTC+1, 0);
90: }
91:
1.1.1.2 ! root 92: unsigned int delaycount; /* calibrated loop variable (1 millisecond) */
! 93:
! 94: #define FIRST_GUESS 0x2000
! 95: findcpuspeed()
! 96: {
! 97: unsigned char low;
! 98: unsigned int remainder;
! 99:
! 100: /* Put counter in count down mode */
! 101: outb(IO_TIMER1+3, 0x34);
! 102: outb(IO_TIMER1, 0xff);
! 103: outb(IO_TIMER1, 0xff);
! 104: delaycount = FIRST_GUESS;
! 105: spinwait(1);
! 106: /* Read the value left in the counter */
! 107: low = inb(IO_TIMER1); /* least siginifcant */
! 108: remainder = inb(IO_TIMER1); /* most significant */
! 109: remainder = (remainder<<8) + low ;
! 110: /* Formula for delaycount is :
! 111: * (loopcount * timer clock speed)/ (counter ticks * 1000)
! 112: */
! 113: delaycount = (FIRST_GUESS * (XTALSPEED/1000)) / (0xffff-remainder);
! 114: }
! 115:
! 116:
! 117:
1.1 root 118: /* convert 2 digit BCD number */
119: bcd(i)
120: int i;
121: {
122: return ((i/16)*10 + (i%16));
123: }
124:
125: /* convert years to seconds (from 1970) */
126: unsigned long
127: ytos(y)
128: int y;
129: {
130: int i;
131: unsigned long ret;
132:
1.1.1.2 ! root 133: ret = 0;
! 134: for(i = 1970; i < y; i++) {
1.1 root 135: if (i % 4) ret += 365*24*60*60;
136: else ret += 366*24*60*60;
137: }
138: return ret;
139: }
140:
141: /* convert months to seconds */
142: unsigned long
143: mtos(m,leap)
144: int m,leap;
145: {
146: int i;
147: unsigned long ret;
148:
149: ret = 0;
150: for(i=1;i<m;i++) {
151: switch(i){
152: case 1: case 3: case 5: case 7: case 8: case 10: case 12:
153: ret += 31*24*60*60; break;
154: case 4: case 6: case 9: case 11:
155: ret += 30*24*60*60; break;
156: case 2:
157: if (leap) ret += 29*24*60*60;
158: else ret += 28*24*60*60;
159: }
160: }
161: return ret;
162: }
163:
164:
165: /*
166: * Initialize the time of day register, based on the time base which is, e.g.
167: * from a filesystem.
168: */
169: inittodr(base)
170: time_t base;
171: {
172: unsigned long sec;
173: int leap,day_week,t,yd;
174: int sa,s;
175:
176: /* do we have a realtime clock present? (otherwise we loop below) */
177: sa = rtcin(RTC_STATUSA);
178: if (sa == 0xff || sa == 0) return;
179:
180: /* ready for a read? */
181: while ((sa&RTCSA_TUP) == RTCSA_TUP)
182: sa = rtcin(RTC_STATUSA);
183:
1.1.1.2 ! root 184: sec = bcd(rtcin(RTC_YEAR)) + 1900;
! 185: if (sec < 1970)
! 186: sec += 100;
! 187: leap = !(sec % 4); sec = ytos(sec); /* year */
1.1 root 188: yd = mtos(bcd(rtcin(RTC_MONTH)),leap); sec += yd; /* month */
189: t = (bcd(rtcin(RTC_DAY))-1) * 24*60*60; sec += t; yd += t; /* date */
190: day_week = rtcin(RTC_WDAY); /* day */
191: sec += bcd(rtcin(RTC_HRS)) * 60*60; /* hour */
192: sec += bcd(rtcin(RTC_MIN)) * 60; /* minutes */
193: sec += bcd(rtcin(RTC_SEC)); /* seconds */
194:
195: /* XXX off by one? Need to calculate DST on SUNDAY */
196: /* Perhaps we should have the RTC hold GMT time to save */
197: /* us the bother of converting. */
1.1.1.2 ! root 198: yd = yd / (24*60*60);
1.1 root 199: if ((yd >= DAYST) && ( yd <= DAYEN)) {
200: sec -= 60*60;
201: }
202: sec += tz.tz_minuteswest * 60;
203:
204: time.tv_sec = sec;
205: }
206:
207: #ifdef garbage
208: /*
209: * Initialze the time of day register, based on the time base which is, e.g.
210: * from a filesystem.
211: */
212: test_inittodr(base)
213: time_t base;
214: {
215:
216: outb(IO_RTC,9); /* year */
217: printf("%d ",bcd(inb(IO_RTC+1)));
218: outb(IO_RTC,8); /* month */
219: printf("%d ",bcd(inb(IO_RTC+1)));
220: outb(IO_RTC,7); /* day */
221: printf("%d ",bcd(inb(IO_RTC+1)));
222: outb(IO_RTC,4); /* hour */
223: printf("%d ",bcd(inb(IO_RTC+1)));
224: outb(IO_RTC,2); /* minutes */
225: printf("%d ",bcd(inb(IO_RTC+1)));
226: outb(IO_RTC,0); /* seconds */
227: printf("%d\n",bcd(inb(IO_RTC+1)));
228:
229: time.tv_sec = base;
230: }
231: #endif
232:
233: /*
234: * Restart the clock.
235: */
236: resettodr()
237: {
238: }
239:
240: /*
241: * Wire clock interrupt in.
242: */
243: #define V(s) __CONCAT(V, s)
244: extern V(clk)();
245: enablertclock() {
246: INTREN(IRQ0);
247: setidt(ICU_OFFSET+0, &V(clk), SDT_SYS386IGT, SEL_KPL);
248: splnone();
249: }
1.1.1.2 ! root 250:
! 251:
! 252:
! 253:
! 254: spinwait(millisecs)
! 255: int millisecs; /* number of milliseconds to delay */
! 256: {
! 257: int i, j;
! 258:
! 259: for (i=0;i<millisecs;i++)
! 260: for (j=0;j<delaycount;j++)
! 261: ;
! 262: }
! 263:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.