xref: /onnv-gate/usr/src/uts/sun4/sys/xc_impl.h (revision 1395:28cb40f27e3d)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
50Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
60Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
70Sstevel@tonic-gate  * with the License.
80Sstevel@tonic-gate  *
90Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate  * See the License for the specific language governing permissions
120Sstevel@tonic-gate  * and limitations under the License.
130Sstevel@tonic-gate  *
140Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate  *
200Sstevel@tonic-gate  * CDDL HEADER END
210Sstevel@tonic-gate  */
220Sstevel@tonic-gate /*
231310Sha137994  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate  * Use is subject to license terms.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate 
270Sstevel@tonic-gate #ifndef	_SYS_XC_IMPL_H
280Sstevel@tonic-gate #define	_SYS_XC_IMPL_H
290Sstevel@tonic-gate 
300Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
310Sstevel@tonic-gate 
320Sstevel@tonic-gate #ifdef	__cplusplus
330Sstevel@tonic-gate extern "C" {
340Sstevel@tonic-gate #endif
350Sstevel@tonic-gate 
360Sstevel@tonic-gate #ifndef _ASM
370Sstevel@tonic-gate 
380Sstevel@tonic-gate #include <sys/note.h>
390Sstevel@tonic-gate #include <sys/cpu_module.h>
400Sstevel@tonic-gate #include <sys/panic.h>		/* for panic_quiesce */
410Sstevel@tonic-gate 
420Sstevel@tonic-gate extern cpuset_t cpu_ready_set;	/* cpus ready for x-call */
430Sstevel@tonic-gate extern void send_self_xcall(struct cpu *, uint64_t, uint64_t, xcfunc_t *);
440Sstevel@tonic-gate extern uint_t xc_loop(void);
450Sstevel@tonic-gate extern uint_t xc_serv(void);
460Sstevel@tonic-gate extern void xc_stop(struct regs *);
470Sstevel@tonic-gate #ifdef TRAPTRACE
480Sstevel@tonic-gate extern void xc_trace(uint_t, cpuset_t *, xcfunc_t *, uint64_t, uint64_t);
490Sstevel@tonic-gate #endif /* TRAPTRACE */
500Sstevel@tonic-gate extern uint64_t xc_func_time_limit;
510Sstevel@tonic-gate 
520Sstevel@tonic-gate extern uint_t sendmondo_in_recover;
530Sstevel@tonic-gate 
540Sstevel@tonic-gate /*
550Sstevel@tonic-gate  * Lightweight XTrap Sync
560Sstevel@tonic-gate  */
570Sstevel@tonic-gate #ifdef sun4v
580Sstevel@tonic-gate #define	XT_SYNC_ONE(cpuid)				\
590Sstevel@tonic-gate {							\
600Sstevel@tonic-gate 	cpuset_t set;					\
610Sstevel@tonic-gate 	CPUSET_ONLY(set, cpuid);			\
620Sstevel@tonic-gate 	xt_sync(set);					\
630Sstevel@tonic-gate }
640Sstevel@tonic-gate 
650Sstevel@tonic-gate #define	XT_SYNC_SOME(cpuset)				\
660Sstevel@tonic-gate {							\
670Sstevel@tonic-gate 	xt_sync(cpuset);				\
680Sstevel@tonic-gate }
690Sstevel@tonic-gate 
700Sstevel@tonic-gate #else /* sun4v */
710Sstevel@tonic-gate 
720Sstevel@tonic-gate #define	XT_SYNC_ONE(cpuid)				\
730Sstevel@tonic-gate {							\
740Sstevel@tonic-gate 	init_mondo((xcfunc_t *)xt_sync_tl1, 0, 0);	\
750Sstevel@tonic-gate 	send_one_mondo(cpuid);				\
760Sstevel@tonic-gate }
770Sstevel@tonic-gate 
780Sstevel@tonic-gate #define	XT_SYNC_SOME(cpuset)				\
790Sstevel@tonic-gate {							\
800Sstevel@tonic-gate 	init_mondo((xcfunc_t *)xt_sync_tl1, 0, 0);	\
810Sstevel@tonic-gate 	send_mondo_set(cpuset);				\
820Sstevel@tonic-gate }
830Sstevel@tonic-gate 
840Sstevel@tonic-gate #endif /* sun4v */
850Sstevel@tonic-gate 
860Sstevel@tonic-gate /*
870Sstevel@tonic-gate  * Protect the dispatching of the mondo vector
880Sstevel@tonic-gate  */
890Sstevel@tonic-gate 
900Sstevel@tonic-gate #define	XC_SPL_ENTER(cpuid, opl)					\
910Sstevel@tonic-gate {									\
920Sstevel@tonic-gate 	opl = splr(XCALL_PIL);						\
930Sstevel@tonic-gate 	cpuid = CPU->cpu_id;						\
940Sstevel@tonic-gate 	if (xc_spl_enter[cpuid] && !panic_quiesce)			\
950Sstevel@tonic-gate 		cmn_err(CE_PANIC, "XC SPL ENTER already entered (0x%x)",\
960Sstevel@tonic-gate 		cpuid);							\
970Sstevel@tonic-gate 	xc_spl_enter[cpuid] = 1;					\
980Sstevel@tonic-gate }
990Sstevel@tonic-gate 
1000Sstevel@tonic-gate #define	XC_SPL_EXIT(cpuid, opl)				\
1010Sstevel@tonic-gate {							\
1020Sstevel@tonic-gate 	ASSERT(xc_spl_enter[cpuid] != 0);		\
1030Sstevel@tonic-gate 	xc_spl_enter[cpuid] = 0;			\
1040Sstevel@tonic-gate 	splx(opl);					\
1050Sstevel@tonic-gate }
1060Sstevel@tonic-gate 
1070Sstevel@tonic-gate /*
1080Sstevel@tonic-gate  * set up a x-call request
1090Sstevel@tonic-gate  */
1100Sstevel@tonic-gate #define	XC_SETUP(cpuid, func, arg1, arg2)		\
1110Sstevel@tonic-gate {							\
1120Sstevel@tonic-gate 	xc_mbox[cpuid].xc_func = func;			\
1130Sstevel@tonic-gate 	xc_mbox[cpuid].xc_arg1 = arg1;			\
1140Sstevel@tonic-gate 	xc_mbox[cpuid].xc_arg2 = arg2;			\
1150Sstevel@tonic-gate 	xc_mbox[cpuid].xc_state = XC_DOIT;		\
1160Sstevel@tonic-gate }
1170Sstevel@tonic-gate 
1180Sstevel@tonic-gate /*
1190Sstevel@tonic-gate  * set up x-call requests to the cpuset
1200Sstevel@tonic-gate  */
1210Sstevel@tonic-gate #define	SEND_MBOX_ONLY(xc_cpuset, func, arg1, arg2, lcx, state)		\
1220Sstevel@tonic-gate {									\
1230Sstevel@tonic-gate 	int pix;							\
1240Sstevel@tonic-gate 	cpuset_t  tmpset = xc_cpuset;					\
1250Sstevel@tonic-gate 	for (pix = 0; pix < NCPU; pix++) {				\
1260Sstevel@tonic-gate 		if (CPU_IN_SET(tmpset, pix)) {				\
1270Sstevel@tonic-gate 			ASSERT(MUTEX_HELD(&xc_sys_mutex));		\
1280Sstevel@tonic-gate 			ASSERT(CPU_IN_SET(xc_mbox[lcx].xc_cpuset, pix));\
1290Sstevel@tonic-gate 			ASSERT(xc_mbox[pix].xc_state == state);		\
1300Sstevel@tonic-gate 			XC_SETUP(pix, func, arg1, arg2);		\
1310Sstevel@tonic-gate 			membar_stld();					\
1320Sstevel@tonic-gate 			CPUSET_DEL(tmpset, pix);			\
1330Sstevel@tonic-gate 			CPU_STATS_ADDQ(CPU, sys, xcalls, 1);		\
1340Sstevel@tonic-gate 			if (CPUSET_ISNULL(tmpset))			\
1350Sstevel@tonic-gate 				break;					\
1360Sstevel@tonic-gate 		}							\
1370Sstevel@tonic-gate 	}								\
1380Sstevel@tonic-gate }
1390Sstevel@tonic-gate 
1400Sstevel@tonic-gate /*
1410Sstevel@tonic-gate  * set up and notify a x-call request to the cpuset
1420Sstevel@tonic-gate  */
1430Sstevel@tonic-gate #define	SEND_MBOX_MONDO(xc_cpuset, func, arg1, arg2, state)	\
1440Sstevel@tonic-gate {								\
1450Sstevel@tonic-gate 	int pix;						\
1460Sstevel@tonic-gate 	cpuset_t  tmpset = xc_cpuset;				\
1470Sstevel@tonic-gate 	for (pix = 0; pix < NCPU; pix++) {			\
1480Sstevel@tonic-gate 		if (CPU_IN_SET(tmpset, pix)) {			\
1490Sstevel@tonic-gate 			ASSERT(xc_mbox[pix].xc_state == state);	\
1500Sstevel@tonic-gate 			XC_SETUP(pix, func, arg1, arg2);	\
1510Sstevel@tonic-gate 			CPUSET_DEL(tmpset, pix);		\
1520Sstevel@tonic-gate 			if (CPUSET_ISNULL(tmpset))		\
1530Sstevel@tonic-gate 				break;				\
1540Sstevel@tonic-gate 		}						\
1550Sstevel@tonic-gate 	}							\
1561310Sha137994 	membar_stld();						\
1571310Sha137994 	send_mondo_set(xc_cpuset);				\
1581310Sha137994 }
1591310Sha137994 
1601310Sha137994 /*
1611310Sha137994  * set up and notify a x-call request, signalling xc_cpuset
1621310Sha137994  * cpus to enter xc_loop()
1631310Sha137994  */
1641310Sha137994 #define	SEND_MBOX_MONDO_XC_ENTER(xc_cpuset)			\
1651310Sha137994 {								\
1661310Sha137994 	int pix;						\
1671310Sha137994 	cpuset_t  tmpset = xc_cpuset;				\
1681310Sha137994 	for (pix = 0; pix < NCPU; pix++) {			\
1691310Sha137994 		if (CPU_IN_SET(tmpset, pix)) {			\
1701310Sha137994 			ASSERT(xc_mbox[pix].xc_state ==		\
1711310Sha137994 			    XC_IDLE);				\
1721310Sha137994 			xc_mbox[pix].xc_state = XC_ENTER;	\
1731310Sha137994 			CPUSET_DEL(tmpset, pix);		\
1741310Sha137994 			if (CPUSET_ISNULL(tmpset)) {		\
1751310Sha137994 				break;				\
1761310Sha137994 			}					\
1771310Sha137994 		}						\
1781310Sha137994 	}							\
1791310Sha137994 	send_mondo_set(xc_cpuset);				\
1800Sstevel@tonic-gate }
1810Sstevel@tonic-gate 
1820Sstevel@tonic-gate /*
1830Sstevel@tonic-gate  * wait x-call requests to be completed
1840Sstevel@tonic-gate  */
1850Sstevel@tonic-gate #define	WAIT_MBOX_DONE(xc_cpuset, lcx, state, sync)			\
1860Sstevel@tonic-gate {									\
1870Sstevel@tonic-gate 	int pix;							\
1880Sstevel@tonic-gate 	uint64_t loop_cnt = 0;						\
1890Sstevel@tonic-gate 	cpuset_t tmpset;						\
1900Sstevel@tonic-gate 	cpuset_t  recv_cpuset;						\
1910Sstevel@tonic-gate 	int first_time = 1;						\
1920Sstevel@tonic-gate 	CPUSET_ZERO(recv_cpuset);					\
1930Sstevel@tonic-gate 	while (!CPUSET_ISEQUAL(recv_cpuset, xc_cpuset)) {		\
1940Sstevel@tonic-gate 		tmpset = xc_cpuset;					\
1950Sstevel@tonic-gate 		for (pix = 0; pix < NCPU; pix++) {			\
1960Sstevel@tonic-gate 			if (CPU_IN_SET(tmpset, pix)) {			\
1970Sstevel@tonic-gate 				if (xc_mbox[pix].xc_state == state) {	\
1980Sstevel@tonic-gate 					CPUSET_ADD(recv_cpuset, pix);	\
1990Sstevel@tonic-gate 				}					\
2000Sstevel@tonic-gate 			}						\
2010Sstevel@tonic-gate 			CPUSET_DEL(tmpset, pix);			\
2020Sstevel@tonic-gate 			if (CPUSET_ISNULL(tmpset))			\
2030Sstevel@tonic-gate 				break;					\
2040Sstevel@tonic-gate 		}							\
2050Sstevel@tonic-gate 		if (loop_cnt++ > xc_func_time_limit) {			\
2060Sstevel@tonic-gate 			if (sendmondo_in_recover) {			\
2070Sstevel@tonic-gate 				drv_usecwait(1);			\
2080Sstevel@tonic-gate 				loop_cnt = 0;				\
2090Sstevel@tonic-gate 				continue;				\
2100Sstevel@tonic-gate 			}						\
2110Sstevel@tonic-gate 			_NOTE(CONSTANTCONDITION)			\
2120Sstevel@tonic-gate 			if (sync && first_time) {			\
2130Sstevel@tonic-gate 				XT_SYNC_SOME(xc_cpuset);		\
2140Sstevel@tonic-gate 				first_time = 0;				\
2150Sstevel@tonic-gate 				loop_cnt = 0;				\
2160Sstevel@tonic-gate 				continue;				\
2170Sstevel@tonic-gate 			}						\
2180Sstevel@tonic-gate 			panic("WAIT_MBOX_DONE() timeout, "		\
2190Sstevel@tonic-gate 				"recv_cpuset 0x%lx, xc cpuset 0x%lx ",	\
2201009Smathue 				*(ulong_t *)&recv_cpuset,		\
2211009Smathue 				*(ulong_t *)&xc_cpuset);		\
2220Sstevel@tonic-gate 		}							\
2230Sstevel@tonic-gate 	}								\
2240Sstevel@tonic-gate }
2250Sstevel@tonic-gate 
2260Sstevel@tonic-gate /*
2270Sstevel@tonic-gate  * xc_state flags
2280Sstevel@tonic-gate  */
2290Sstevel@tonic-gate enum xc_states {
2300Sstevel@tonic-gate 	XC_IDLE = 0,	/* not in the xc_loop(); set by xc_loop */
2310Sstevel@tonic-gate 	XC_ENTER,	/* entering xc_loop(); set by xc_attention */
2320Sstevel@tonic-gate 	XC_WAIT,	/* entered xc_loop(); set by xc_loop */
2330Sstevel@tonic-gate 	XC_DOIT,	/* xcall request; set by xc_one, xc_some, or xc_all */
2340Sstevel@tonic-gate 	XC_EXIT		/* exiting xc_loop(); set by xc_dismissed */
2350Sstevel@tonic-gate };
2360Sstevel@tonic-gate 
2370Sstevel@tonic-gate /*
2380Sstevel@tonic-gate  * user provided handlers must be pc aligned
2390Sstevel@tonic-gate  */
2400Sstevel@tonic-gate #define	PC_ALIGN 4
2410Sstevel@tonic-gate 
2420Sstevel@tonic-gate #ifdef TRAPTRACE
2430Sstevel@tonic-gate #define	XC_TRACE(type, cpus, func, arg1, arg2) \
2440Sstevel@tonic-gate 		xc_trace((type), (cpus), (func), (arg1), (arg2))
2450Sstevel@tonic-gate #else /* !TRAPTRACE */
2460Sstevel@tonic-gate #define	XC_TRACE(type, cpus, func, arg1, arg2)
2470Sstevel@tonic-gate #endif /* TRAPTRACE */
2480Sstevel@tonic-gate 
249*1395Srjnoe #if defined(DEBUG) || defined(TRAPTRACE)
2500Sstevel@tonic-gate /*
2510Sstevel@tonic-gate  * get some statistics when xc/xt routines are called
2520Sstevel@tonic-gate  */
2530Sstevel@tonic-gate 
2540Sstevel@tonic-gate #define	XC_STAT_INC(a)	(a)++;
2550Sstevel@tonic-gate #define	XC_CPUID	0
2560Sstevel@tonic-gate 
2570Sstevel@tonic-gate #define	XT_ONE_SELF	1
2580Sstevel@tonic-gate #define	XT_ONE_OTHER	2
2590Sstevel@tonic-gate #define	XT_SOME_SELF	3
2600Sstevel@tonic-gate #define	XT_SOME_OTHER	4
2610Sstevel@tonic-gate #define	XT_ALL_SELF	5
2620Sstevel@tonic-gate #define	XT_ALL_OTHER	6
2630Sstevel@tonic-gate #define	XC_ONE_SELF	7
2640Sstevel@tonic-gate #define	XC_ONE_OTHER	8
2650Sstevel@tonic-gate #define	XC_ONE_OTHER_H	9
2660Sstevel@tonic-gate #define	XC_SOME_SELF	10
2670Sstevel@tonic-gate #define	XC_SOME_OTHER	11
2680Sstevel@tonic-gate #define	XC_SOME_OTHER_H	12
2690Sstevel@tonic-gate #define	XC_ALL_SELF	13
2700Sstevel@tonic-gate #define	XC_ALL_OTHER	14
2710Sstevel@tonic-gate #define	XC_ALL_OTHER_H	15
2720Sstevel@tonic-gate #define	XC_ATTENTION	16
2730Sstevel@tonic-gate #define	XC_DISMISSED	17
2740Sstevel@tonic-gate #define	XC_LOOP_ENTER	18
2750Sstevel@tonic-gate #define	XC_LOOP_DOIT	19
2760Sstevel@tonic-gate #define	XC_LOOP_EXIT	20
2770Sstevel@tonic-gate 
2780Sstevel@tonic-gate extern	uint_t x_dstat[NCPU][XC_LOOP_EXIT+1];
2790Sstevel@tonic-gate extern	uint_t x_rstat[NCPU][4];
2800Sstevel@tonic-gate #define	XC_LOOP		1
2810Sstevel@tonic-gate #define	XC_SERV		2
2820Sstevel@tonic-gate 
2830Sstevel@tonic-gate #define	XC_STAT_INIT(cpuid) 				\
2840Sstevel@tonic-gate {							\
2850Sstevel@tonic-gate 	x_dstat[cpuid][XC_CPUID] = 0xffffff00 | cpuid;	\
2860Sstevel@tonic-gate 	x_rstat[cpuid][XC_CPUID] = 0xffffff00 | cpuid;	\
2870Sstevel@tonic-gate }
2880Sstevel@tonic-gate 
289*1395Srjnoe #else /* DEBUG || TRAPTRACE */
2900Sstevel@tonic-gate 
2910Sstevel@tonic-gate #define	XC_STAT_INIT(cpuid)
2920Sstevel@tonic-gate #define	XC_STAT_INC(a)
2930Sstevel@tonic-gate #define	XC_ATTENTION_CPUSET(x)
2940Sstevel@tonic-gate #define	XC_DISMISSED_CPUSET(x)
2950Sstevel@tonic-gate 
296*1395Srjnoe #endif /* DEBUG || TRAPTRACE */
2970Sstevel@tonic-gate 
2980Sstevel@tonic-gate #endif	/* !_ASM */
2990Sstevel@tonic-gate 
3000Sstevel@tonic-gate /*
3010Sstevel@tonic-gate  * Maximum delay in milliseconds to wait for send_mondo to complete
3020Sstevel@tonic-gate  */
3030Sstevel@tonic-gate #define	XC_SEND_MONDO_MSEC	1000
3040Sstevel@tonic-gate 
3050Sstevel@tonic-gate #ifdef	__cplusplus
3060Sstevel@tonic-gate }
3070Sstevel@tonic-gate #endif
3080Sstevel@tonic-gate 
3090Sstevel@tonic-gate #endif	/* _SYS_XC_IMPL_H */
310