]>
git.saurik.com Git - apple/xnu.git/blob - osfmk/i386/AT386/bbclock.c
3849e7194cd9a91f695ffdf29e85eec6ef728ff2
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_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 License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
32 Copyright 1988, 1989 by Intel Corporation, Santa Clara, California.
36 Permission to use, copy, modify, and distribute this software and
37 its documentation for any purpose and without fee is hereby
38 granted, provided that the above copyright notice appears in all
39 copies and that both the copyright notice and this permission notice
40 appear in supporting documentation, and that the name of Intel
41 not be used in advertising or publicity pertaining to distribution
42 of the software without specific, written prior permission.
44 INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
45 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
46 IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
47 CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
48 LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
49 NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
50 WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
54 #include <mach/message.h>
55 #include <kern/thread.h>
56 #include <kern/clock.h>
58 #include <kern/processor.h>
59 #include <kern/misc_protos.h>
60 #include <i386/cpu_data.h>
61 #include <i386/cpu_number.h>
63 #include <i386/AT386/rtc.h>
64 #include <i386/AT386/bbclock_entries.h>
67 static int month
[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
69 extern char dectohexdec(
71 extern int hexdectodec(
76 struct rtc_st
* regs
);
78 struct rtc_st
* regs
);
80 #define LOCK_BBC() splclock()
81 #define UNLOCK_BBC(s) splx(s)
84 * Configure battery-backed clock.
92 mp_disable_preemption();
93 if (cpu_number() != master_cpu
) {
94 mp_enable_preemption();
101 outb(RTC_ADDR
, RTC_A
);
102 outb(RTC_DATA
, RTC_DIV2
| RTC_RATE6
);
103 outb(RTC_ADDR
, RTC_B
);
104 outb(RTC_DATA
, RTC_HM
);
107 * Probe the device by trying to read it.
109 BbcFlag
= (rtcget(&rtclk
) ? 0 : 1);
111 printf("battery clock configured\n");
113 printf("WARNING: Battery Clock Failure!\n");
114 mp_enable_preemption();
119 * Get the current clock time.
123 mach_timespec_t
*cur_time
) /* OUT */
127 int sec
, min
, hr
, dom
, mon
, yr
;
132 if ((thread
= current_thread()) != THREAD_NULL
) {
133 thread_bind(thread
, master_processor
);
134 mp_disable_preemption();
135 if (current_processor() != master_processor
) {
136 mp_enable_preemption();
137 thread_block(THREAD_CONTINUE_NULL
);
139 mp_enable_preemption();
145 sec
= hexdectodec(rtclk
.rtc_sec
);
146 min
= hexdectodec(rtclk
.rtc_min
);
147 hr
= hexdectodec(rtclk
.rtc_hr
);
148 dom
= hexdectodec(rtclk
.rtc_dom
);
149 mon
= hexdectodec(rtclk
.rtc_mon
);
150 yr
= hexdectodec(rtclk
.rtc_yr
);
151 yr
= (yr
< 70) ? yr
+100 : yr
;
152 n
= sec
+ 60 * min
+ 3600 * hr
;
153 n
+= (dom
- 1) * 3600 * 24;
154 if (yeartoday(yr
) == 366)
156 for (i
= mon
- 2; i
>= 0; i
--)
159 for (i
= 70; i
< yr
; i
++)
160 days
+= yeartoday(i
);
161 n
+= days
* 3600 * 24;
162 cur_time
->tv_sec
= n
;
163 cur_time
->tv_nsec
= 0;
166 if (thread
!= THREAD_NULL
)
167 thread_bind(thread
, PROCESSOR_NULL
);
168 return (KERN_SUCCESS
);
172 * Set the current clock time.
176 mach_timespec_t
*new_time
)
184 if ((thread
= current_thread()) != THREAD_NULL
) {
185 thread_bind(thread
, master_processor
);
186 mp_disable_preemption();
187 if (current_processor() != master_processor
) {
188 mp_enable_preemption();
189 thread_block(THREAD_CONTINUE_NULL
);
191 mp_enable_preemption();
198 n
= (new_time
->tv_sec
- diff
) % (3600 * 24); /* hrs+mins+secs */
199 rtclk
.rtc_sec
= dectohexdec(n%60
);
201 rtclk
.rtc_min
= dectohexdec(n%60
);
202 rtclk
.rtc_hr
= dectohexdec(n
/60);
203 n
= (new_time
->tv_sec
- diff
) / (3600 * 24); /* days */
204 rtclk
.rtc_dow
= (n
+ 4) % 7; /* 1/1/70 is Thursday */
205 for (j
= 70; n
>= (i
= yeartoday(j
)); j
++)
207 rtclk
.rtc_yr
= dectohexdec(j
% 100);
208 if (yeartoday(j
) == 366)
210 for (i
= 0; n
>= month
[i
]; i
++)
213 rtclk
.rtc_mon
= dectohexdec(++i
);
214 rtclk
.rtc_dom
= dectohexdec(++n
);
218 if (thread
!= THREAD_NULL
)
219 thread_bind(current_thread(), PROCESSOR_NULL
);
221 return (KERN_SUCCESS
);
225 /* DEVICE SPECIFIC ROUTINES */
229 struct rtc_st
* regs
)
231 outb(RTC_ADDR
, RTC_D
);
232 if ((inb(RTC_DATA
) & RTC_VRT
) == 0)
234 outb(RTC_ADDR
, RTC_A
);
235 while (inb(RTC_DATA
) & RTC_UIP
) /* busy wait */
236 outb(RTC_ADDR
, RTC_A
);
237 load_rtc((unsigned char *)regs
);
243 struct rtc_st
* regs
)
245 register unsigned char x
;
247 outb(RTC_ADDR
, RTC_B
);
249 outb(RTC_ADDR
, RTC_B
);
250 outb(RTC_DATA
, x
| RTC_SET
);
251 save_rtc((unsigned char *)regs
);
252 outb(RTC_ADDR
, RTC_B
);
253 outb(RTC_DATA
, x
& ~RTC_SET
);
261 return((year
% 4) ? 365 :
262 ((year
% 100) ? 366 : ((year
% 400) ? 365: 366)));
269 return ((((n
>> 4) & 0x0F) * 10) + (n
& 0x0F));
276 return ((char)(((n
/ 10) << 4) & 0xF0) | ((n
% 10) & 0x0F));