]>
git.saurik.com Git - apple/xnu.git/blob - osfmk/i386/AT386/bbclock.c
cefba69305c364a2a4319a68900ed16f10a376a5
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_OSREFERENCE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the
10 * License may not be used to create, or enable the creation or
11 * redistribution of, unlawful or unlicensed copies of an Apple operating
12 * system, or to circumvent, violate, or enable the circumvention or
13 * violation of, any terms of an Apple operating system software license
16 * Please obtain a copy of the License at
17 * http://www.opensource.apple.com/apsl/ and read it before using this
20 * The Original Code and all software distributed under the License are
21 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
22 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
23 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
25 * Please see the License for the specific language governing rights and
26 * limitations under the License.
28 * @APPLE_LICENSE_OSREFERENCE_HEADER_END@
34 Copyright 1988, 1989 by Intel Corporation, Santa Clara, California.
38 Permission to use, copy, modify, and distribute this software and
39 its documentation for any purpose and without fee is hereby
40 granted, provided that the above copyright notice appears in all
41 copies and that both the copyright notice and this permission notice
42 appear in supporting documentation, and that the name of Intel
43 not be used in advertising or publicity pertaining to distribution
44 of the software without specific, written prior permission.
46 INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
47 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
48 IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
49 CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
50 LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
51 NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
52 WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
56 #include <mach/message.h>
57 #include <kern/thread.h>
58 #include <kern/clock.h>
60 #include <kern/processor.h>
61 #include <kern/misc_protos.h>
62 #include <i386/cpu_data.h>
63 #include <i386/cpu_number.h>
65 #include <i386/AT386/rtc.h>
66 #include <i386/AT386/bbclock_entries.h>
69 static int month
[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
71 extern char dectohexdec(
73 extern int hexdectodec(
78 struct rtc_st
* regs
);
80 struct rtc_st
* regs
);
82 #define LOCK_BBC() splclock()
83 #define UNLOCK_BBC(s) splx(s)
86 * Configure battery-backed clock.
94 mp_disable_preemption();
95 if (cpu_number() != master_cpu
) {
96 mp_enable_preemption();
103 outb(RTC_ADDR
, RTC_A
);
104 outb(RTC_DATA
, RTC_DIV2
| RTC_RATE6
);
105 outb(RTC_ADDR
, RTC_B
);
106 outb(RTC_DATA
, RTC_HM
);
109 * Probe the device by trying to read it.
111 BbcFlag
= (rtcget(&rtclk
) ? 0 : 1);
113 printf("battery clock configured\n");
115 printf("WARNING: Battery Clock Failure!\n");
116 mp_enable_preemption();
121 * Get the current clock time.
125 mach_timespec_t
*cur_time
) /* OUT */
129 int sec
, min
, hr
, dom
, mon
, yr
;
134 if ((thread
= current_thread()) != THREAD_NULL
) {
135 thread_bind(thread
, master_processor
);
136 mp_disable_preemption();
137 if (current_processor() != master_processor
) {
138 mp_enable_preemption();
139 thread_block(THREAD_CONTINUE_NULL
);
141 mp_enable_preemption();
147 sec
= hexdectodec(rtclk
.rtc_sec
);
148 min
= hexdectodec(rtclk
.rtc_min
);
149 hr
= hexdectodec(rtclk
.rtc_hr
);
150 dom
= hexdectodec(rtclk
.rtc_dom
);
151 mon
= hexdectodec(rtclk
.rtc_mon
);
152 yr
= hexdectodec(rtclk
.rtc_yr
);
153 yr
= (yr
< 70) ? yr
+100 : yr
;
154 n
= sec
+ 60 * min
+ 3600 * hr
;
155 n
+= (dom
- 1) * 3600 * 24;
156 if (yeartoday(yr
) == 366)
158 for (i
= mon
- 2; i
>= 0; i
--)
161 for (i
= 70; i
< yr
; i
++)
162 days
+= yeartoday(i
);
163 n
+= days
* 3600 * 24;
164 cur_time
->tv_sec
= n
;
165 cur_time
->tv_nsec
= 0;
168 if (thread
!= THREAD_NULL
)
169 thread_bind(thread
, PROCESSOR_NULL
);
170 return (KERN_SUCCESS
);
174 * Set the current clock time.
178 mach_timespec_t
*new_time
)
186 if ((thread
= current_thread()) != THREAD_NULL
) {
187 thread_bind(thread
, master_processor
);
188 mp_disable_preemption();
189 if (current_processor() != master_processor
) {
190 mp_enable_preemption();
191 thread_block(THREAD_CONTINUE_NULL
);
193 mp_enable_preemption();
200 n
= (new_time
->tv_sec
- diff
) % (3600 * 24); /* hrs+mins+secs */
201 rtclk
.rtc_sec
= dectohexdec(n%60
);
203 rtclk
.rtc_min
= dectohexdec(n%60
);
204 rtclk
.rtc_hr
= dectohexdec(n
/60);
205 n
= (new_time
->tv_sec
- diff
) / (3600 * 24); /* days */
206 rtclk
.rtc_dow
= (n
+ 4) % 7; /* 1/1/70 is Thursday */
207 for (j
= 70; n
>= (i
= yeartoday(j
)); j
++)
209 rtclk
.rtc_yr
= dectohexdec(j
% 100);
210 if (yeartoday(j
) == 366)
212 for (i
= 0; n
>= month
[i
]; i
++)
215 rtclk
.rtc_mon
= dectohexdec(++i
);
216 rtclk
.rtc_dom
= dectohexdec(++n
);
220 if (thread
!= THREAD_NULL
)
221 thread_bind(current_thread(), PROCESSOR_NULL
);
223 return (KERN_SUCCESS
);
227 /* DEVICE SPECIFIC ROUTINES */
231 struct rtc_st
* regs
)
233 outb(RTC_ADDR
, RTC_D
);
234 if ((inb(RTC_DATA
) & RTC_VRT
) == 0)
236 outb(RTC_ADDR
, RTC_A
);
237 while (inb(RTC_DATA
) & RTC_UIP
) /* busy wait */
238 outb(RTC_ADDR
, RTC_A
);
239 load_rtc((unsigned char *)regs
);
245 struct rtc_st
* regs
)
247 register unsigned char x
;
249 outb(RTC_ADDR
, RTC_B
);
251 outb(RTC_ADDR
, RTC_B
);
252 outb(RTC_DATA
, x
| RTC_SET
);
253 save_rtc((unsigned char *)regs
);
254 outb(RTC_ADDR
, RTC_B
);
255 outb(RTC_DATA
, x
& ~RTC_SET
);
263 return((year
% 4) ? 365 :
264 ((year
% 100) ? 366 : ((year
% 400) ? 365: 366)));
271 return ((((n
>> 4) & 0x0F) * 10) + (n
& 0x0F));
278 return ((char)(((n
/ 10) << 4) & 0xF0) | ((n
% 10) & 0x0F));