auto conf, bus control, conventions, interrupt control, per host config
[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
6 * William Jolitz.
7 *
cc60f649
DA
8 * Added stuff to read the cmos clock on startup - Don Ahn
9 *
f21663b5
WN
10 * %sccs.include.386.c%
11 *
4686adac 12 * @(#)clock.c 5.4 (Berkeley) %G%
f21663b5
WN
13 */
14
15/*
16 * Primitive clock interrupt routines.
17 */
18#include "param.h"
19#include "time.h"
20#include "kernel.h"
4686adac
BJ
21#include "machine/segments.h"
22#include "machine/isa/icu.h"
23#include "machine/isa/isa.h"
f21663b5 24
cc60f649
DA
25#define DAYST 119
26#define DAYEN 303
27
f21663b5
WN
28startrtclock() {
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);
f21663b5
WN
34}
35
cc60f649
DA
36/* convert 2 digit BCD number */
37bcd(i)
38int i;
39{
40 return ((i/16)*10 + (i%16));
41}
42
43/* convert years to seconds (from 1970) */
44unsigned long
45ytos(y)
46int y;
47{
48 int i;
49 unsigned long ret;
50
51 ret = 0; y = y - 70;
52 for(i=0;i<y;i++) {
53 if (i % 4) ret += 31536000;
54 else ret += 31622400;
55 }
56 return ret;
57}
58
59/* convert months to seconds */
60unsigned long
61mtos(m,leap)
62int m,leap;
63{
64 int i;
65 unsigned long ret;
66
67 ret = 0;
68 for(i=1;i<m;i++) {
69 switch(i){
70 case 1: case 3: case 5: case 7: case 8: case 10: case 12:
71 ret += 2678400; break;
72 case 4: case 6: case 9: case 11:
73 ret += 2592000; break;
74 case 2:
75 if (leap) ret += 2505600;
76 else ret += 2419200;
77 }
78 }
79 return ret;
80}
81
82
f21663b5 83/*
5b97e489 84 * Initialize the time of day register, based on the time base which is, e.g.
f21663b5
WN
85 * from a filesystem.
86 */
87inittodr(base)
88 time_t base;
89{
cc60f649
DA
90 unsigned long sec;
91 int leap,day_week,t,yd;
92
5b97e489
BJ
93 sec = bcd(rtcin(9)); leap = !(sec % 4); sec += ytos(sec); /* year */
94 yd = mtos(bcd(rtcin(8)),leap); sec += yd; /* month */
95 t = (bcd(rtcin(7))-1) * 86400; sec += t; yd += t; /* date */
96 day_week = rtcin(6); /* day */
97 sec += bcd(rtcin(4)) * 3600; /* hour */
98 sec += bcd(rtcin(2)) * 60; /* minutes */
99 sec += bcd(rtcin(0)); /* seconds */
cc60f649
DA
100
101 /* XXX off by one? Need to calculate DST on SUNDAY */
102 /* Perhaps we should have the RTC hold GMT time to save */
103 /* us the bother of converting. */
104 yd = yd / 86400;
105 if ((yd >= DAYST) && ( yd <= DAYEN)) {
106 sec -= 3600;
107 }
108 sec += tz.tz_minuteswest * 60;
109
110 time.tv_sec = sec;
111}
112
5b97e489 113#ifdef garbage
cc60f649
DA
114/*
115 * Initialze the time of day register, based on the time base which is, e.g.
116 * from a filesystem.
117 */
118test_inittodr(base)
119 time_t base;
120{
121
5b97e489
BJ
122 outb(IO_RTC,9); /* year */
123 printf("%d ",bcd(inb(IO_RTC+1)));
124 outb(IO_RTC,8); /* month */
125 printf("%d ",bcd(inb(IO_RTC+1)));
126 outb(IO_RTC,7); /* day */
127 printf("%d ",bcd(inb(IO_RTC+1)));
128 outb(IO_RTC,4); /* hour */
129 printf("%d ",bcd(inb(IO_RTC+1)));
130 outb(IO_RTC,2); /* minutes */
131 printf("%d ",bcd(inb(IO_RTC+1)));
132 outb(IO_RTC,0); /* seconds */
133 printf("%d\n",bcd(inb(IO_RTC+1)));
f21663b5
WN
134
135 time.tv_sec = base;
136}
5b97e489 137#endif
f21663b5 138
5b97e489
BJ
139/*
140 * retreve a value from realtime clock
141 */
142u_char rtcin(n) {
143 u_char val;
144
145 outb(IO_RTC,n);
146 do val = inb(IO_RTC+1) ; while (val != inb(IO_RTC+1));
147 return (val);
148}
cc60f649 149
f21663b5
WN
150/*
151 * Restart the clock.
152 */
153resettodr()
154{
155}
156
4686adac
BJ
157#define V(s) V/**/s
158extern V(clk)();
f21663b5
WN
159enablertclock() {
160 INTREN(IRQ0);
4686adac 161 setidt(ICU_OFFSET+0, &V(clk), SDT_SYS386IGT, SEL_KPL);
f21663b5
WN
162 splnone();
163}