pass flags through device close
[unix-history] / usr / src / sys / i386 / isa / clock.c
CommitLineData
f21663b5
WN
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
d4a75cc0 6 * William Jolitz and Don Ahn.
f21663b5 7 *
d4a75cc0 8 * %sccs.include.redist.c%
cc60f649 9 *
187497c9 10 * @(#)clock.c 7.2 (Berkeley) %G%
f21663b5
WN
11 */
12
13/*
14 * Primitive clock interrupt routines.
15 */
16#include "param.h"
17#include "time.h"
18#include "kernel.h"
4686adac 19#include "machine/segments.h"
8dfab1b8
WN
20#include "i386/isa/icu.h"
21#include "i386/isa/isa.h"
22#include "i386/isa/rtc.h"
f21663b5 23
cc60f649
DA
24#define DAYST 119
25#define DAYEN 303
26
f21663b5 27startrtclock() {
8dfab1b8 28 int s;
f21663b5
WN
29
30 /* initialize 8253 clock */
4686adac
BJ
31 outb (IO_TIMER1+3, 0x36);
32 outb (IO_TIMER1, 1193182/hz);
33 outb (IO_TIMER1, (1193182/hz)/256);
8dfab1b8 34
8dfab1b8
WN
35 /* initialize brain-dead battery powered clock */
36 outb (IO_RTC, RTC_STATUSA);
37 outb (IO_RTC+1, 0x26);
38 outb (IO_RTC, RTC_STATUSB);
39 outb (IO_RTC+1, 2);
40
8dfab1b8
WN
41 outb (IO_RTC, RTC_DIAG);
42 if (s = inb (IO_RTC+1))
43 printf("RTC BIOS diagnostic error %b\n", s, RTCDG_BITS);
44 outb (IO_RTC, RTC_DIAG);
45 outb (IO_RTC+1, 0);
f21663b5
WN
46}
47
cc60f649
DA
48/* convert 2 digit BCD number */
49bcd(i)
50int i;
51{
52 return ((i/16)*10 + (i%16));
53}
54
55/* convert years to seconds (from 1970) */
56unsigned long
57ytos(y)
58int y;
59{
60 int i;
61 unsigned long ret;
62
63 ret = 0; y = y - 70;
64 for(i=0;i<y;i++) {
8dfab1b8
WN
65 if (i % 4) ret += 365*24*60*60;
66 else ret += 366*24*60*60;
cc60f649
DA
67 }
68 return ret;
69}
70
71/* convert months to seconds */
72unsigned long
73mtos(m,leap)
74int m,leap;
75{
76 int i;
77 unsigned long ret;
78
79 ret = 0;
80 for(i=1;i<m;i++) {
81 switch(i){
82 case 1: case 3: case 5: case 7: case 8: case 10: case 12:
8dfab1b8 83 ret += 31*24*60*60; break;
cc60f649 84 case 4: case 6: case 9: case 11:
8dfab1b8 85 ret += 30*24*60*60; break;
cc60f649 86 case 2:
8dfab1b8
WN
87 if (leap) ret += 29*24*60*60;
88 else ret += 28*24*60*60;
cc60f649
DA
89 }
90 }
91 return ret;
92}
93
94
f21663b5 95/*
5b97e489 96 * Initialize the time of day register, based on the time base which is, e.g.
f21663b5
WN
97 * from a filesystem.
98 */
99inittodr(base)
100 time_t base;
101{
cc60f649
DA
102 unsigned long sec;
103 int leap,day_week,t,yd;
187497c9 104 int sa,s;
8dfab1b8
WN
105
106 /* do we have a realtime clock present? (otherwise we loop below) */
107 sa = rtcin(RTC_STATUSA);
108 if (sa == 0xff || sa == 0) return;
109
110 /* ready for a read? */
111 while ((sa&RTCSA_TUP) == RTCSA_TUP)
112 sa = rtcin(RTC_STATUSA);
113
114 sec = bcd(rtcin(RTC_YEAR));
115 leap = !(sec % 4); sec += ytos(sec); /* year */
116 yd = mtos(bcd(rtcin(RTC_MONTH)),leap); sec += yd; /* month */
117 t = (bcd(rtcin(RTC_DAY))-1) * 24*60*60; sec += t; yd += t; /* date */
118 day_week = rtcin(RTC_WDAY); /* day */
119 sec += bcd(rtcin(RTC_HRS)) * 60*60; /* hour */
120 sec += bcd(rtcin(RTC_MIN)) * 60; /* minutes */
121 sec += bcd(rtcin(RTC_SEC)); /* seconds */
122 sec -= 24*60*60; /* XXX why ??? */
123
124#ifdef notdef
cc60f649
DA
125 /* XXX off by one? Need to calculate DST on SUNDAY */
126 /* Perhaps we should have the RTC hold GMT time to save */
127 /* us the bother of converting. */
8dfab1b8 128 yd = yd / 24*60*60;
cc60f649 129 if ((yd >= DAYST) && ( yd <= DAYEN)) {
8dfab1b8 130 sec -= 60*60;
cc60f649 131 }
8dfab1b8 132#endif
cc60f649
DA
133 sec += tz.tz_minuteswest * 60;
134
135 time.tv_sec = sec;
136}
137
5b97e489 138#ifdef garbage
cc60f649
DA
139/*
140 * Initialze the time of day register, based on the time base which is, e.g.
141 * from a filesystem.
142 */
143test_inittodr(base)
144 time_t base;
145{
146
5b97e489
BJ
147 outb(IO_RTC,9); /* year */
148 printf("%d ",bcd(inb(IO_RTC+1)));
149 outb(IO_RTC,8); /* month */
150 printf("%d ",bcd(inb(IO_RTC+1)));
151 outb(IO_RTC,7); /* day */
152 printf("%d ",bcd(inb(IO_RTC+1)));
153 outb(IO_RTC,4); /* hour */
154 printf("%d ",bcd(inb(IO_RTC+1)));
155 outb(IO_RTC,2); /* minutes */
156 printf("%d ",bcd(inb(IO_RTC+1)));
157 outb(IO_RTC,0); /* seconds */
158 printf("%d\n",bcd(inb(IO_RTC+1)));
f21663b5
WN
159
160 time.tv_sec = base;
161}
5b97e489 162#endif
f21663b5
WN
163
164/*
165 * Restart the clock.
166 */
167resettodr()
168{
169}
170
187497c9
WN
171/*
172 * Wire clock interrupt in.
173 */
8dfab1b8 174#define V(s) __CONCAT(V, s)
4686adac 175extern V(clk)();
f21663b5
WN
176enablertclock() {
177 INTREN(IRQ0);
4686adac 178 setidt(ICU_OFFSET+0, &V(clk), SDT_SYS386IGT, SEL_KPL);
f21663b5
WN
179 splnone();
180}