xref: /titanic_51/usr/src/uts/sun4u/sys/machclock.h (revision 023e71de9e5670cebc23dd51162833661d3d2d3b)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
525cf1a30Sjl139090  * Common Development and Distribution License (the "License").
625cf1a30Sjl139090  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22*023e71deSHaik Aftandilian  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #ifndef _SYS_MACHCLOCK_H
277c478bd9Sstevel@tonic-gate #define	_SYS_MACHCLOCK_H
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
307c478bd9Sstevel@tonic-gate extern "C" {
317c478bd9Sstevel@tonic-gate #endif
327c478bd9Sstevel@tonic-gate 
337c478bd9Sstevel@tonic-gate #ifdef _ASM
347c478bd9Sstevel@tonic-gate /*
357c478bd9Sstevel@tonic-gate  * Macro to clear the NPT (non-privileged trap) bit in the %tick/%stick
367c478bd9Sstevel@tonic-gate  * register.  Uses %g1-%g4.
377c478bd9Sstevel@tonic-gate  */
387c478bd9Sstevel@tonic-gate #define	CLEARTICKNPT				\
397c478bd9Sstevel@tonic-gate 	sethi	%hi(cpu_clearticknpt), %g1;	\
407c478bd9Sstevel@tonic-gate 	jmp	%g1 + %lo(cpu_clearticknpt);	\
417c478bd9Sstevel@tonic-gate 	rd	%pc, %g4
427c478bd9Sstevel@tonic-gate 
43*023e71deSHaik Aftandilian #define	RD_TICK_NO_SUSPEND_CHECK(out, scr1)	\
44*023e71deSHaik Aftandilian 	rdpr	%tick, out;			\
45*023e71deSHaik Aftandilian 	sllx	out, 1, out;			\
46*023e71deSHaik Aftandilian 	srlx	out, 1, out;
47*023e71deSHaik Aftandilian 
48*023e71deSHaik Aftandilian #define	RD_TICK(out, scr1, scr2, label)		\
49*023e71deSHaik Aftandilian 	RD_TICK_NO_SUSPEND_CHECK(out, scr1);
50*023e71deSHaik Aftandilian 
517c478bd9Sstevel@tonic-gate #endif /* _ASM */
527c478bd9Sstevel@tonic-gate 
537c478bd9Sstevel@tonic-gate #if defined(CPU_MODULE)
547c478bd9Sstevel@tonic-gate 
557c478bd9Sstevel@tonic-gate /*
567c478bd9Sstevel@tonic-gate  * Constants used to convert hi-res timestamps into nanoseconds
577c478bd9Sstevel@tonic-gate  * (see <sys/clock.h> file for more information)
587c478bd9Sstevel@tonic-gate  */
597c478bd9Sstevel@tonic-gate 
6025cf1a30Sjl139090 #if defined(CHEETAH) || defined(HUMMINGBIRD) || defined(OLYMPUS_C)
617c478bd9Sstevel@tonic-gate 
627c478bd9Sstevel@tonic-gate /*
637c478bd9Sstevel@tonic-gate  * At least 3.9MHz, for slower %stick-based systems.
647c478bd9Sstevel@tonic-gate  */
657c478bd9Sstevel@tonic-gate #define	NSEC_SHIFT	8
667c478bd9Sstevel@tonic-gate 
677c478bd9Sstevel@tonic-gate #elif defined(SPITFIRE)
687c478bd9Sstevel@tonic-gate 
697c478bd9Sstevel@tonic-gate /*
707c478bd9Sstevel@tonic-gate  * At least 62.5 MHz, for faster %tick-based systems.
717c478bd9Sstevel@tonic-gate  */
727c478bd9Sstevel@tonic-gate #define	NSEC_SHIFT	4
737c478bd9Sstevel@tonic-gate #define	VTRACE_SHIFT	4
747c478bd9Sstevel@tonic-gate 
757c478bd9Sstevel@tonic-gate #else
767c478bd9Sstevel@tonic-gate #error "Compiling for CPU_MODULE but no CPU specified"
777c478bd9Sstevel@tonic-gate #endif
787c478bd9Sstevel@tonic-gate 
79*023e71deSHaik Aftandilian /*
80*023e71deSHaik Aftandilian  * NOTE: the macros below assume that the various time-related variables
81*023e71deSHaik Aftandilian  * (hrestime, hrestime_adj, hres_last_tick, timedelta, nsec_scale, etc)
82*023e71deSHaik Aftandilian  * are all stored together on a 64-byte boundary.  The primary motivation
83*023e71deSHaik Aftandilian  * is cache performance, but we also take advantage of a convenient side
84*023e71deSHaik Aftandilian  * effect: these variables all have the same high 22 address bits, so only
85*023e71deSHaik Aftandilian  * one sethi is needed to access them all.
86*023e71deSHaik Aftandilian  */
87*023e71deSHaik Aftandilian 
88*023e71deSHaik Aftandilian /*
89*023e71deSHaik Aftandilian  * GET_HRESTIME() returns the value of hrestime, hrestime_adj and the
90*023e71deSHaik Aftandilian  * number of nanoseconds since the last clock tick ('nslt').  It also
91*023e71deSHaik Aftandilian  * sets 'nano' to the value NANOSEC (one billion).
92*023e71deSHaik Aftandilian  *
93*023e71deSHaik Aftandilian  * This macro assumes that all registers are globals or outs so they can
94*023e71deSHaik Aftandilian  * safely contain 64-bit data, and that it's safe to use the label "5:".
95*023e71deSHaik Aftandilian  * Further, this macro calls the NATIVE_TIME_TO_NSEC_SCALE which in turn
96*023e71deSHaik Aftandilian  * uses the labels "6:" and "7:"; labels "5:", "6:" and "7:" must not
97*023e71deSHaik Aftandilian  * be used across invocations of this macro.
98*023e71deSHaik Aftandilian  */
99*023e71deSHaik Aftandilian #define	GET_HRESTIME(hrestsec, hrestnsec, adj, nslt, nano, scr, hrlock, \
100*023e71deSHaik Aftandilian     gnt1, gnt2) \
101*023e71deSHaik Aftandilian 5:	sethi	%hi(hres_lock), scr;					\
102*023e71deSHaik Aftandilian 	lduw	[scr + %lo(hres_lock)], hrlock;	/* load clock lock */	\
103*023e71deSHaik Aftandilian 	lduw	[scr + %lo(nsec_scale)], nano;	/* tick-to-ns factor */	\
104*023e71deSHaik Aftandilian 	andn	hrlock, 1, hrlock;  	/* see comments above! */	\
105*023e71deSHaik Aftandilian 	ldx	[scr + %lo(hres_last_tick)], nslt;			\
106*023e71deSHaik Aftandilian 	ldn	[scr + %lo(hrestime)], hrestsec; /* load hrestime.sec */\
107*023e71deSHaik Aftandilian 	add	scr, %lo(hrestime), hrestnsec;				\
108*023e71deSHaik Aftandilian 	ldn	[hrestnsec + CLONGSIZE], hrestnsec;			\
109*023e71deSHaik Aftandilian 	GET_NATIVE_TIME(adj, gnt1, gnt2);	/* get current %tick */	\
110*023e71deSHaik Aftandilian 	subcc	adj, nslt, nslt; /* nslt = ticks since last clockint */	\
111*023e71deSHaik Aftandilian 	movneg	%xcc, %g0, nslt; /* ignore neg delta from tick skew */	\
112*023e71deSHaik Aftandilian 	ldx	[scr + %lo(hrestime_adj)], adj; /* load hrestime_adj */	\
113*023e71deSHaik Aftandilian 	/* membar #LoadLoad; (see comment (2) above) */			\
114*023e71deSHaik Aftandilian 	lduw	[scr + %lo(hres_lock)], scr; /* load clock lock */	\
115*023e71deSHaik Aftandilian 	NATIVE_TIME_TO_NSEC_SCALE(nslt, nano, gnt1, NSEC_SHIFT);	\
116*023e71deSHaik Aftandilian 	sethi	%hi(NANOSEC), nano;					\
117*023e71deSHaik Aftandilian 	xor	hrlock, scr, scr;					\
118*023e71deSHaik Aftandilian /* CSTYLED */ 								\
119*023e71deSHaik Aftandilian 	brnz,pn	scr, 5b;						\
120*023e71deSHaik Aftandilian 	or	nano, %lo(NANOSEC), nano;
121*023e71deSHaik Aftandilian 
122*023e71deSHaik Aftandilian /*
123*023e71deSHaik Aftandilian  * Similar to above, but returns current gethrtime() value in 'base'.
124*023e71deSHaik Aftandilian  */
125*023e71deSHaik Aftandilian #define	GET_HRTIME(base, now, nslt, scale, scr, hrlock, gnt1, gnt2)	\
126*023e71deSHaik Aftandilian 5:	sethi	%hi(hres_lock), scr;					\
127*023e71deSHaik Aftandilian 	lduw	[scr + %lo(hres_lock)], hrlock;	/* load clock lock */	\
128*023e71deSHaik Aftandilian 	lduw	[scr + %lo(nsec_scale)], scale;	/* tick-to-ns factor */	\
129*023e71deSHaik Aftandilian 	andn	hrlock, 1, hrlock;  	/* see comments above! */	\
130*023e71deSHaik Aftandilian 	ldx	[scr + %lo(hres_last_tick)], nslt;			\
131*023e71deSHaik Aftandilian 	ldx	[scr + %lo(hrtime_base)], base;	/* load hrtime_base */	\
132*023e71deSHaik Aftandilian 	GET_NATIVE_TIME(now, gnt1, gnt2);	/* get current %tick */	\
133*023e71deSHaik Aftandilian 	subcc	now, nslt, nslt; /* nslt = ticks since last clockint */	\
134*023e71deSHaik Aftandilian 	movneg	%xcc, %g0, nslt; /* ignore neg delta from tick skew */	\
135*023e71deSHaik Aftandilian 	/* membar #LoadLoad; (see comment (2) above) */			\
136*023e71deSHaik Aftandilian 	ld	[scr + %lo(hres_lock)], scr; /* load clock lock */	\
137*023e71deSHaik Aftandilian 	NATIVE_TIME_TO_NSEC_SCALE(nslt, scale, gnt1, NSEC_SHIFT);	\
138*023e71deSHaik Aftandilian 	xor	hrlock, scr, scr;					\
139*023e71deSHaik Aftandilian /* CSTYLED */ 								\
140*023e71deSHaik Aftandilian 	brnz,pn	scr, 5b;						\
141*023e71deSHaik Aftandilian 	add	base, nslt, base;
142*023e71deSHaik Aftandilian 
1437c478bd9Sstevel@tonic-gate #endif /* CPU_MODULE */
1447c478bd9Sstevel@tonic-gate 
1457c478bd9Sstevel@tonic-gate #ifndef _ASM
1467c478bd9Sstevel@tonic-gate 
1477c478bd9Sstevel@tonic-gate #ifdef	_KERNEL
1487c478bd9Sstevel@tonic-gate 
1497c478bd9Sstevel@tonic-gate /*
1507c478bd9Sstevel@tonic-gate  * Hardware watchdog variables and knobs
1517c478bd9Sstevel@tonic-gate  */
1527c478bd9Sstevel@tonic-gate 
1537c478bd9Sstevel@tonic-gate #define	CLK_WATCHDOG_DEFAULT	10	/* 10 seconds */
1547c478bd9Sstevel@tonic-gate 
1557c478bd9Sstevel@tonic-gate extern int	watchdog_enable;
1567c478bd9Sstevel@tonic-gate extern int	watchdog_available;
1577c478bd9Sstevel@tonic-gate extern int	watchdog_activated;
1587c478bd9Sstevel@tonic-gate extern uint_t	watchdog_timeout_seconds;
1597c478bd9Sstevel@tonic-gate 
1607c478bd9Sstevel@tonic-gate /*
1617c478bd9Sstevel@tonic-gate  * tod module name and operations
1627c478bd9Sstevel@tonic-gate  */
1637c478bd9Sstevel@tonic-gate struct tod_ops {
1647c478bd9Sstevel@tonic-gate 	timestruc_t	(*tod_get)(void);
1657c478bd9Sstevel@tonic-gate 	void		(*tod_set)(timestruc_t);
1667c478bd9Sstevel@tonic-gate 	uint_t		(*tod_set_watchdog_timer)(uint_t);
1677c478bd9Sstevel@tonic-gate 	uint_t		(*tod_clear_watchdog_timer)(void);
1687c478bd9Sstevel@tonic-gate 	void		(*tod_set_power_alarm)(timestruc_t);
1697c478bd9Sstevel@tonic-gate 	void		(*tod_clear_power_alarm)(void);
1707c478bd9Sstevel@tonic-gate 	uint64_t	(*tod_get_cpufrequency)(void);
1717c478bd9Sstevel@tonic-gate };
1727c478bd9Sstevel@tonic-gate 
1737c478bd9Sstevel@tonic-gate extern struct tod_ops	tod_ops;
1747c478bd9Sstevel@tonic-gate extern char		*tod_module_name;
1757c478bd9Sstevel@tonic-gate 
1762df1fe9cSrandyf /*
1772df1fe9cSrandyf  * These defines allow common code to use TOD functions independant
1782df1fe9cSrandyf  * of hardware platform.
1792df1fe9cSrandyf  */
1802df1fe9cSrandyf #define	TODOP_GET(top)		((top).tod_get())
1812df1fe9cSrandyf #define	TODOP_SET(top, ts)	((top).tod_set(ts))
1822df1fe9cSrandyf #define	TODOP_SETWD(top, nsec)	((top).tod_set_watchdog_timer(nsec))
1832df1fe9cSrandyf #define	TODOP_CLRWD(top)	((top).tod_clear_watchdog_timer())
1842df1fe9cSrandyf #define	TODOP_SETWAKE(top, ts)	((top).tod_set_power_alarm(ts))
1852df1fe9cSrandyf #define	TODOP_CLRWAKE(top)	((top).tod_clear_power_alarm())
1862df1fe9cSrandyf 
1877c478bd9Sstevel@tonic-gate #endif	/* _KERNEL */
1887c478bd9Sstevel@tonic-gate 
1897c478bd9Sstevel@tonic-gate #endif	/* _ASM */
1907c478bd9Sstevel@tonic-gate 
1917c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
1927c478bd9Sstevel@tonic-gate }
1937c478bd9Sstevel@tonic-gate #endif
1947c478bd9Sstevel@tonic-gate 
1957c478bd9Sstevel@tonic-gate #endif	/* !_SYS_MACHCLOCK_H */
196