BSD 4_2 release
[unix-history] / usr / src / sys / vax / clock.c
CommitLineData
61c578c4
C
1/* clock.c 6.1 83/07/29 */
2
3#include "../h/param.h"
4#include "../h/time.h"
5#include "../h/kernel.h"
6
7#include "../vax/mtpr.h"
8#include "../vax/clock.h"
9
10/*
11 * Machine-dependent clock routines.
12 *
13 * Startrtclock restarts the real-time clock, which provides
14 * hardclock interrupts to kern_clock.c.
15 *
16 * Inittodr initializes the time of day hardware which provides
17 * date functions. Its primary function is to use some file
18 * system information in case the hardare clock lost state.
19 *
20 * Resettodr restores the time of day hardware after a time change.
21 */
22
23/*
24 * Start the real-time clock.
25 */
26startrtclock()
27{
28
29 mtpr(NICR, -1000000/hz);
30 mtpr(ICCS, ICCS_RUN+ICCS_IE+ICCS_TRANS+ICCS_INT+ICCS_ERR);
31}
32
33/*
34 * Initialze the time of day register, based on the time base which is, e.g.
35 * from a filesystem. Base provides the time to within six months,
36 * and the time of year clock provides the rest.
37 */
38inittodr(base)
39 time_t base;
40{
41 register u_int todr = mfpr(TODR);
42 long deltat;
43 int year = YRREF;
44
45 if (base < 5*SECYR) {
46 printf("WARNING: preposterous time in file system");
47 time.tv_sec = 6*SECYR + 186*SECDAY + SECDAY/2;
48 resettodr();
49 goto check;
50 }
51 /*
52 * TODRZERO is base used by VMS, which runs on local time.
53 */
54 if (todr < TODRZERO) {
55 printf("WARNING: todr too small");
56 time.tv_sec = base;
57 /*
58 * Believe the time in the file system for lack of
59 * anything better, resetting the TODR.
60 */
61 resettodr();
62 goto check;
63 }
64
65 /*
66 * Sneak to within 6 month of the time in the filesystem,
67 * by starting with the time of the year suggested by the TODR,
68 * and advancing through succesive years. Adding the number of
69 * seconds in the current year takes us to the end of the current year
70 * and then around into the next year to the same position.
71 */
72 time.tv_sec = (todr-TODRZERO)/100;
73 while (time.tv_sec < base-SECYR/2) {
74 if (LEAPYEAR(year))
75 time.tv_sec += SECDAY;
76 year++;
77 time.tv_sec += SECYR;
78 }
79
80 /*
81 * See if we gained/lost two or more days;
82 * if so, assume something is amiss.
83 */
84 deltat = time.tv_sec - base;
85 if (deltat < 0)
86 deltat = -deltat;
87 if (deltat < 2*SECDAY)
88 return;
89 printf("WARNING: clock %s %d days",
90 time.tv_sec < base ? "lost" : "gained", deltat / SECDAY);
91check:
92 printf(" -- CHECK AND RESET THE DATE!\n");
93}
94
95/*
96 * Reset the TODR based on the time value; used when the TODR
97 * has a preposterous value and also when the time is reset
98 * by the stime system call. Also called when the TODR goes past
99 * TODRZERO + 100*(SECYEAR+2*SECDAY) (e.g. on Jan 2 just after midnight)
100 * to wrap the TODR around.
101 */
102resettodr()
103{
104 int year = YRREF;
105 u_int secyr;
106 u_int yrtime = time.tv_sec;
107
108 /*
109 * Whittle the time down to an offset in the current year,
110 * by subtracting off whole years as long as possible.
111 */
112 for (;;) {
113 secyr = SECYR;
114 if (LEAPYEAR(year))
115 secyr += SECDAY;
116 if (yrtime < secyr)
117 break;
118 yrtime -= secyr;
119 year++;
120 }
121 mtpr(TODR, TODRZERO + yrtime*100);
122}