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