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
114struct 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
121int adjkerntz;		/* local offset from GMT in seconds */
122int clkintr_pending;
123int pscnt = 1;
124int psdiv = 1;
125int wall_cmos_clock;
126u_int timer_freq = TIMER_FREQ;
127static u_long cyc2ns_scale;
128static uint64_t processed_system_time;	/* stime (ns) at last processing. */
129
130extern 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 */
162static inline void set_cyc2ns_scale(unsigned long cpu_mhz)
163{
164	cyc2ns_scale = (1000 << CYC2NS_SCALE_FACTOR)/cpu_mhz;
165}
166
167static inline unsigned long long cycles_2_ns(unsigned long long cyc)
168{
169	return ((cyc * cyc2ns_scale) >> CYC2NS_SCALE_FACTOR);
170}
171
172static uint32_t
173getit(void)
174{
175	return (xen_timer_last_time);
176}
177
178
179/*
180 * XXX: timer needs more SMP work.
181 */
182void
183i8254_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 */
194void
195DELAY(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
279void
280startrtclock()
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
310static __inline int
311readrtc(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 */
323static void
324domu_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 */
354static void
355domu_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 */
394void
395inittodr(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 */
475void
476resettodr()
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 */
539void
540cpu_initclocks(void)
541{
542	cpu_initclocks_bsp();
543}
544
545/* Return system time offset by ticks */
546uint64_t
547get_system_time(int ticks)
548{
549    return (processed_system_time + (ticks * NS_PER_TICK));
550}
551
552int
553timer_spkr_acquire(void)
554{
555
556	return (0);
557}
558
559int
560timer_spkr_release(void)
561{
562
563	return (0);
564}
565
566void
567timer_spkr_setfreq(int freq)
568{
569
570}
571
572