]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - sys/i386/xen/clock.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / sys / i386 / xen / clock.c
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 and Don Ahn.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:
18  *      This product includes software developed by the University of
19  *      California, Berkeley and its contributors.
20  * 4. Neither the name of the University nor the names of its contributors
21  *    may be used to endorse or promote products derived from this software
22  *    without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  *
36  *      from: @(#)clock.c       7.2 (Berkeley) 5/12/91
37  */
38
39 #include <sys/cdefs.h>
40 __FBSDID("$FreeBSD$");
41
42 /* #define DELAYDEBUG */
43 /*
44  * Routines to handle clock hardware.
45  */
46
47 #include "opt_ddb.h"
48 #include "opt_clock.h"
49
50 #include <sys/param.h>
51 #include <sys/systm.h>
52 #include <sys/bus.h>
53 #include <sys/clock.h>
54 #include <sys/lock.h>
55 #include <sys/mutex.h>
56 #include <sys/proc.h>
57 #include <sys/time.h>
58 #include <sys/timeet.h>
59 #include <sys/timetc.h>
60 #include <sys/kernel.h>
61 #include <sys/limits.h>
62 #include <sys/sysctl.h>
63 #include <sys/cons.h>
64 #include <sys/power.h>
65
66 #include <machine/clock.h>
67 #include <machine/cputypes.h>
68 #include <machine/frame.h>
69 #include <machine/intr_machdep.h>
70 #include <machine/md_var.h>
71 #include <machine/psl.h>
72 #if defined(SMP)
73 #include <machine/smp.h>
74 #endif
75 #include <machine/specialreg.h>
76 #include <machine/timerreg.h>
77
78 #include <x86/isa/icu.h>
79 #include <x86/isa/isa.h>
80 #include <isa/rtc.h>
81
82 #include <vm/vm.h>
83 #include <vm/pmap.h>
84 #include <machine/pmap.h>
85 #include <xen/hypervisor.h>
86 #include <xen/xen-os.h>
87 #include <machine/xen/xenfunc.h>
88 #include <xen/interface/vcpu.h>
89 #include <machine/cpu.h>
90 #include <xen/xen_intr.h>
91
92 /*
93  * 32-bit time_t's can't reach leap years before 1904 or after 2036, so we
94  * can use a simple formula for leap years.
95  */
96 #define LEAPYEAR(y)     (!((y) % 4))
97 #define DAYSPERYEAR     (28+30*4+31*7)
98
99 #ifndef TIMER_FREQ
100 #define TIMER_FREQ      1193182
101 #endif
102
103 #ifdef CYC2NS_SCALE_FACTOR
104 #undef  CYC2NS_SCALE_FACTOR
105 #endif
106 #define CYC2NS_SCALE_FACTOR     10
107
108 /* Values for timerX_state: */
109 #define RELEASED        0
110 #define RELEASE_PENDING 1
111 #define ACQUIRED        2
112 #define ACQUIRE_PENDING 3
113
114 struct mtx clock_lock;
115 #define RTC_LOCK_INIT                                                   \
116         mtx_init(&clock_lock, "clk", NULL, MTX_SPIN | MTX_NOPROFILE)
117 #define RTC_LOCK        mtx_lock_spin(&clock_lock)
118 #define RTC_UNLOCK      mtx_unlock_spin(&clock_lock)
119 #define NS_PER_TICK     (1000000000ULL/hz)
120
121 int adjkerntz;          /* local offset from GMT in seconds */
122 int clkintr_pending;
123 int pscnt = 1;
124 int psdiv = 1;
125 int wall_cmos_clock;
126 u_int timer_freq = TIMER_FREQ;
127 static u_long cyc2ns_scale; 
128 static uint64_t processed_system_time;  /* stime (ns) at last processing. */
129
130 extern volatile uint64_t xen_timer_last_time;
131
132 #define do_div(n,base) ({ \
133         unsigned long __upper, __low, __high, __mod, __base; \
134         __base = (base); \
135         __asm("":"=a" (__low), "=d" (__high):"A" (n)); \
136         __upper = __high; \
137         if (__high) { \
138                 __upper = __high % (__base); \
139                 __high = __high / (__base); \
140         } \
141         __asm("divl %2":"=a" (__low), "=d" (__mod):"rm" (__base), "0" (__low), "1" (__upper)); \
142         __asm("":"=A" (n):"a" (__low),"d" (__high)); \
143         __mod; \
144 })
145
146
147 /* convert from cycles(64bits) => nanoseconds (64bits)
148  *  basic equation:
149  *              ns = cycles / (freq / ns_per_sec)
150  *              ns = cycles * (ns_per_sec / freq)
151  *              ns = cycles * (10^9 / (cpu_mhz * 10^6))
152  *              ns = cycles * (10^3 / cpu_mhz)
153  *
154  *      Then we use scaling math (suggested by george@mvista.com) to get:
155  *              ns = cycles * (10^3 * SC / cpu_mhz) / SC
156  *              ns = cycles * cyc2ns_scale / SC
157  *
158  *      And since SC is a constant power of two, we can convert the div
159  *  into a shift.   
160  *                      -johnstul@us.ibm.com "math is hard, lets go shopping!"
161  */
162 static inline void set_cyc2ns_scale(unsigned long cpu_mhz)
163 {
164         cyc2ns_scale = (1000 << CYC2NS_SCALE_FACTOR)/cpu_mhz;
165 }
166
167 static inline unsigned long long cycles_2_ns(unsigned long long cyc)
168 {
169         return ((cyc * cyc2ns_scale) >> CYC2NS_SCALE_FACTOR);
170 }
171
172 static uint32_t
173 getit(void)
174 {
175         return (xen_timer_last_time);
176 }
177
178
179 /*
180  * XXX: timer needs more SMP work.
181  */
182 void
183 i8254_init(void)
184 {
185
186         RTC_LOCK_INIT;
187 }
188
189 /*
190  * Wait "n" microseconds.
191  * Relies on timer 1 counting down from (timer_freq / hz)
192  * Note: timer had better have been programmed before this is first used!
193  */
194 void
195 DELAY(int n)
196 {
197         int delta, ticks_left;
198         uint32_t tick, prev_tick;
199 #ifdef DELAYDEBUG
200         int getit_calls = 1;
201         int n1;
202         static int state = 0;
203
204         if (state == 0) {
205                 state = 1;
206                 for (n1 = 1; n1 <= 10000000; n1 *= 10)
207                         DELAY(n1);
208                 state = 2;
209         }
210         if (state == 1)
211                 printf("DELAY(%d)...", n);
212 #endif
213         /*
214          * Read the counter first, so that the rest of the setup overhead is
215          * counted.  Guess the initial overhead is 20 usec (on most systems it
216          * takes about 1.5 usec for each of the i/o's in getit().  The loop
217          * takes about 6 usec on a 486/33 and 13 usec on a 386/20.  The
218          * multiplications and divisions to scale the count take a while).
219          *
220          * However, if ddb is active then use a fake counter since reading
221          * the i8254 counter involves acquiring a lock.  ddb must not go
222          * locking for many reasons, but it calls here for at least atkbd
223          * input.
224          */
225         prev_tick = getit();
226
227         n -= 0;                 /* XXX actually guess no initial overhead */
228         /*
229          * Calculate (n * (timer_freq / 1e6)) without using floating point
230          * and without any avoidable overflows.
231          */
232         if (n <= 0)
233                 ticks_left = 0;
234         else if (n < 256)
235                 /*
236                  * Use fixed point to avoid a slow division by 1000000.
237                  * 39099 = 1193182 * 2^15 / 10^6 rounded to nearest.
238                  * 2^15 is the first power of 2 that gives exact results
239                  * for n between 0 and 256.
240                  */
241                 ticks_left = ((u_int)n * 39099 + (1 << 15) - 1) >> 15;
242         else
243                 /*
244                  * Don't bother using fixed point, although gcc-2.7.2
245                  * generates particularly poor code for the long long
246                  * division, since even the slow way will complete long
247                  * before the delay is up (unless we're interrupted).
248                  */
249                 ticks_left = ((u_int)n * (long long)timer_freq + 999999)
250                         / 1000000;
251
252         while (ticks_left > 0) {
253                 tick = getit();
254 #ifdef DELAYDEBUG
255                 ++getit_calls;
256 #endif
257                 delta = tick - prev_tick;
258                 prev_tick = tick;
259                 if (delta < 0) {
260                         /*
261                          * Guard against timer0_max_count being wrong.
262                          * This shouldn't happen in normal operation,
263                          * but it may happen if set_timer_freq() is
264                          * traced.
265                          */
266                         /* delta += timer0_max_count; ??? */
267                         if (delta < 0)
268                                 delta = 0;
269                 }
270                 ticks_left -= delta;
271         }
272 #ifdef DELAYDEBUG
273         if (state == 1)
274                 printf(" %d calls to getit() at %d usec each\n",
275                        getit_calls, (n + 5) / getit_calls);
276 #endif
277 }
278
279 void
280 startrtclock()
281 {
282         uint64_t __cpu_khz;
283         uint32_t cpu_khz;
284         struct vcpu_time_info *info;
285
286         __cpu_khz = 1000000ULL << 32;
287         info = &HYPERVISOR_shared_info->vcpu_info[0].time;
288
289         (void)do_div(__cpu_khz, info->tsc_to_system_mul);
290         if ( info->tsc_shift < 0 )
291                 cpu_khz = __cpu_khz << -info->tsc_shift;
292         else
293                 cpu_khz = __cpu_khz >> info->tsc_shift;
294
295         printf("Xen reported: %u.%03u MHz processor.\n", 
296                cpu_khz / 1000, cpu_khz % 1000);
297
298         /* (10^6 * 2^32) / cpu_hz = (10^3 * 2^32) / cpu_khz =
299            (2^32 * 1 / (clocks/us)) */
300
301         set_cyc2ns_scale(cpu_khz/1000);
302         tsc_freq = cpu_khz * 1000;
303 }
304
305 /*
306  * RTC support routines
307  */
308
309
310 static __inline int
311 readrtc(int port)
312 {
313         return(bcd2bin(rtcin(port)));
314 }
315
316
317 #ifdef XEN_PRIVILEGED_GUEST
318
319 /*
320  * Initialize the time of day register, based on the time base which is, e.g.
321  * from a filesystem.
322  */
323 static void
324 domu_inittodr(time_t base)
325 {
326         unsigned long   sec;
327         int             s, y;
328         struct timespec ts;
329
330         update_wallclock();
331         add_uptime_to_wallclock();
332         
333         RTC_LOCK;
334         
335         if (base) {
336                 ts.tv_sec = base;
337                 ts.tv_nsec = 0;
338                 tc_setclock(&ts);
339         }
340
341         sec += tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0);
342
343         y = time_second - shadow_tv.tv_sec;
344         if (y <= -2 || y >= 2) {
345                 /* badly off, adjust it */
346                 tc_setclock(&shadow_tv);
347         }
348         RTC_UNLOCK;
349 }
350
351 /*
352  * Write system time back to RTC.  
353  */
354 static void
355 domu_resettodr(void)
356 {
357         unsigned long tm;
358         int s;
359         dom0_op_t op;
360         struct shadow_time_info *shadow;
361         struct pcpu *pc;
362
363         pc = pcpu_find(smp_processor_id());
364         shadow = &pc->pc_shadow_time;
365         if (xen_disable_rtc_set)
366                 return;
367         
368         s = splclock();
369         tm = time_second;
370         splx(s);
371         
372         tm -= tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0);
373         
374         if ((xen_start_info->flags & SIF_INITDOMAIN) &&
375             !independent_wallclock)
376         {
377                 op.cmd = DOM0_SETTIME;
378                 op.u.settime.secs        = tm;
379                 op.u.settime.nsecs       = 0;
380                 op.u.settime.system_time = shadow->system_timestamp;
381                 HYPERVISOR_dom0_op(&op);
382                 update_wallclock();
383                 add_uptime_to_wallclock();
384         } else if (independent_wallclock) {
385                 /* notyet */
386                 ;
387         }               
388 }
389
390 /*
391  * Initialize the time of day register, based on the time base which is, e.g.
392  * from a filesystem.
393  */
394 void
395 inittodr(time_t base)
396 {
397         unsigned long   sec, days;
398         int             year, month;
399         int             y, m, s;
400         struct timespec ts;
401
402         if (!(xen_start_info->flags & SIF_INITDOMAIN)) {
403                 domu_inittodr(base);
404                 return;
405         }
406
407         if (base) {
408                 s = splclock();
409                 ts.tv_sec = base;
410                 ts.tv_nsec = 0;
411                 tc_setclock(&ts);
412                 splx(s);
413         }
414
415         /* Look if we have a RTC present and the time is valid */
416         if (!(rtcin(RTC_STATUSD) & RTCSD_PWR))
417                 goto wrong_time;
418
419         /* wait for time update to complete */
420         /* If RTCSA_TUP is zero, we have at least 244us before next update */
421         s = splhigh();
422         while (rtcin(RTC_STATUSA) & RTCSA_TUP) {
423                 splx(s);
424                 s = splhigh();
425         }
426
427         days = 0;
428 #ifdef USE_RTC_CENTURY
429         year = readrtc(RTC_YEAR) + readrtc(RTC_CENTURY) * 100;
430 #else
431         year = readrtc(RTC_YEAR) + 1900;
432         if (year < 1970)
433                 year += 100;
434 #endif
435         if (year < 1970) {
436                 splx(s);
437                 goto wrong_time;
438         }
439         month = readrtc(RTC_MONTH);
440         for (m = 1; m < month; m++)
441                 days += daysinmonth[m-1];
442         if ((month > 2) && LEAPYEAR(year))
443                 days ++;
444         days += readrtc(RTC_DAY) - 1;
445         for (y = 1970; y < year; y++)
446                 days += DAYSPERYEAR + LEAPYEAR(y);
447         sec = ((( days * 24 +
448                   readrtc(RTC_HRS)) * 60 +
449                 readrtc(RTC_MIN)) * 60 +
450                readrtc(RTC_SEC));
451         /* sec now contains the number of seconds, since Jan 1 1970,
452            in the local time zone */
453
454         sec += tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0);
455
456         y = time_second - sec;
457         if (y <= -2 || y >= 2) {
458                 /* badly off, adjust it */
459                 ts.tv_sec = sec;
460                 ts.tv_nsec = 0;
461                 tc_setclock(&ts);
462         }
463         splx(s);
464         return;
465
466  wrong_time:
467         printf("Invalid time in real time clock.\n");
468         printf("Check and reset the date immediately!\n");
469 }
470
471
472 /*
473  * Write system time back to RTC
474  */
475 void
476 resettodr()
477 {
478         unsigned long   tm;
479         int             y, m, s;
480
481         if (!(xen_start_info->flags & SIF_INITDOMAIN)) {
482                 domu_resettodr();
483                 return;
484         }
485                
486         if (xen_disable_rtc_set)
487                 return;
488
489         s = splclock();
490         tm = time_second;
491         splx(s);
492
493         /* Disable RTC updates and interrupts. */
494         writertc(RTC_STATUSB, RTCSB_HALT | RTCSB_24HR);
495
496         /* Calculate local time to put in RTC */
497
498         tm -= tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0);
499
500         writertc(RTC_SEC, bin2bcd(tm%60)); tm /= 60;    /* Write back Seconds */
501         writertc(RTC_MIN, bin2bcd(tm%60)); tm /= 60;    /* Write back Minutes */
502         writertc(RTC_HRS, bin2bcd(tm%24)); tm /= 24;    /* Write back Hours   */
503
504         /* We have now the days since 01-01-1970 in tm */
505         writertc(RTC_WDAY, (tm + 4) % 7 + 1);           /* Write back Weekday */
506         for (y = 1970, m = DAYSPERYEAR + LEAPYEAR(y);
507              tm >= m;
508              y++,      m = DAYSPERYEAR + LEAPYEAR(y))
509                 tm -= m;
510
511         /* Now we have the years in y and the day-of-the-year in tm */
512         writertc(RTC_YEAR, bin2bcd(y%100));             /* Write back Year    */
513 #ifdef USE_RTC_CENTURY
514         writertc(RTC_CENTURY, bin2bcd(y/100));          /* ... and Century    */
515 #endif
516         for (m = 0; ; m++) {
517                 int ml;
518
519                 ml = daysinmonth[m];
520                 if (m == 1 && LEAPYEAR(y))
521                         ml++;
522                 if (tm < ml)
523                         break;
524                 tm -= ml;
525         }
526
527         writertc(RTC_MONTH, bin2bcd(m + 1));            /* Write back Month   */
528         writertc(RTC_DAY, bin2bcd(tm + 1));             /* Write back Month Day */
529
530         /* Reenable RTC updates and interrupts. */
531         writertc(RTC_STATUSB, RTCSB_24HR);
532         rtcin(RTC_INTR);
533 }
534 #endif
535
536 /*
537  * Start clocks running.
538  */
539 void
540 cpu_initclocks(void)
541 {
542         cpu_initclocks_bsp();
543 }
544
545 /* Return system time offset by ticks */
546 uint64_t
547 get_system_time(int ticks)
548 {
549     return (processed_system_time + (ticks * NS_PER_TICK));
550 }
551
552 int
553 timer_spkr_acquire(void)
554 {
555
556         return (0);
557 }
558
559 int
560 timer_spkr_release(void)
561 {
562
563         return (0);
564 }
565
566 void
567 timer_spkr_setfreq(int freq)
568 {
569
570 }
571