* Copyright (c) 1990 The Regents of the University of California.
* This code is derived from software contributed to Berkeley by
* Added stuff to read the cmos clock on startup - Don Ahn
* @(#)clock.c 5.5 (Berkeley) %G%
* Primitive clock interrupt routines.
#include "machine/segments.h"
#include "i386/isa/icu.h"
#include "i386/isa/isa.h"
#include "i386/isa/rtc.h"
/* initialize 8253 clock */
outb (IO_TIMER1
+3, 0x36);
outb (IO_TIMER1
, 1193182/hz
);
outb (IO_TIMER1
, (1193182/hz
)/256);
/* NMI fail safe 1/4 sec */
/* initialize 8253 clock */
outb (IO_TIMER2
+3, 0x30);
outb (IO_TIMER2
, 298300*40);
outb (IO_TIMER2
, (298300*40)/256);
/* initialize brain-dead battery powered clock */
outb (IO_RTC
, RTC_STATUSA
);
outb (IO_RTC
, RTC_STATUSB
);
/*outb (IO_RTC, RTC_STATUSD);
if((inb(IO_RTC+1) & 0x80) == 0)
printf("rtc lost power\n");
outb (IO_RTC, RTC_STATUSD);
printf("RTC BIOS diagnostic error %b\n", s
, RTCDG_BITS
);
outb (IO_TIMER2
+3, 0x30);
outb (IO_TIMER2
, 298300*40);
outb (IO_TIMER2
, (298300*40)/256);
/* convert 2 digit BCD number */
return ((i
/16)*10 + (i
%16));
/* convert years to seconds (from 1970) */
if (i
% 4) ret
+= 365*24*60*60;
else ret
+= 366*24*60*60;
/* convert months to seconds */
case 1: case 3: case 5: case 7: case 8: case 10: case 12:
ret
+= 31*24*60*60; break;
case 4: case 6: case 9: case 11:
ret
+= 30*24*60*60; break;
if (leap
) ret
+= 29*24*60*60;
* Initialize the time of day register, based on the time base which is, e.g.
/* do we have a realtime clock present? (otherwise we loop below) */
if (sa
== 0xff || sa
== 0) return;
while ((sa
&RTCSA_TUP
) == RTCSA_TUP
)
sec
= bcd(rtcin(RTC_YEAR
));
leap
= !(sec
% 4); sec
+= ytos(sec
); /* year */
yd
= mtos(bcd(rtcin(RTC_MONTH
)),leap
); sec
+= yd
; /* month */
t
= (bcd(rtcin(RTC_DAY
))-1) * 24*60*60; sec
+= t
; yd
+= t
; /* date */
day_week
= rtcin(RTC_WDAY
); /* day */
sec
+= bcd(rtcin(RTC_HRS
)) * 60*60; /* hour */
sec
+= bcd(rtcin(RTC_MIN
)) * 60; /* minutes */
sec
+= bcd(rtcin(RTC_SEC
)); /* seconds */
sec
-= 24*60*60; /* XXX why ??? */
/* XXX off by one? Need to calculate DST on SUNDAY */
/* Perhaps we should have the RTC hold GMT time to save */
/* us the bother of converting. */
if ((yd
>= DAYST
) && ( yd
<= DAYEN
)) {
sec
+= tz
.tz_minuteswest
* 60;
* Initialze the time of day register, based on the time base which is, e.g.
outb(IO_RTC
,9); /* year */
printf("%d ",bcd(inb(IO_RTC
+1)));
outb(IO_RTC
,8); /* month */
printf("%d ",bcd(inb(IO_RTC
+1)));
outb(IO_RTC
,7); /* day */
printf("%d ",bcd(inb(IO_RTC
+1)));
outb(IO_RTC
,4); /* hour */
printf("%d ",bcd(inb(IO_RTC
+1)));
outb(IO_RTC
,2); /* minutes */
printf("%d ",bcd(inb(IO_RTC
+1)));
outb(IO_RTC
,0); /* seconds */
printf("%d\n",bcd(inb(IO_RTC
+1)));
* retreve a value from realtime clock
/*outb(IO_RTC, RTC_STATUSA);
do val = inb(IO_RTC+1) ; while (val&0x80);*/
do val
= inb(IO_RTC
+1) ; while (val
!= inb(IO_RTC
+1));
#define V(s) __CONCAT(V, s)
setidt(ICU_OFFSET
+0, &V(clk
), SDT_SYS386IGT
, SEL_KPL
);