|
|
1.1 root 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: */
26: startrtclock()
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: */
38: inittodr(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);
91: check:
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: */
102: resettodr()
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.