xref: /illumos-gate/usr/src/uts/sun4u/sys/machthread.h (revision febcc4a52c3ed7fe3a106da2c2ba52c56afd5111)
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
525cf1a30Sjl  * Common Development and Distribution License (the "License").
625cf1a30Sjl  * 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*febcc4a5Sjimand  * Copyright 2007 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_MACHTHREAD_H
277c478bd9Sstevel@tonic-gate #define	_SYS_MACHTHREAD_H
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
307c478bd9Sstevel@tonic-gate 
317c478bd9Sstevel@tonic-gate #include <sys/asi.h>
327c478bd9Sstevel@tonic-gate #include <sys/sun4asi.h>
337c478bd9Sstevel@tonic-gate #include <sys/machasi.h>
347c478bd9Sstevel@tonic-gate #include <sys/bitmap.h>
3525cf1a30Sjl #include <sys/opl_olympus_regs.h>
367c478bd9Sstevel@tonic-gate 
377c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
387c478bd9Sstevel@tonic-gate extern "C" {
397c478bd9Sstevel@tonic-gate #endif
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate #ifdef	_ASM
427c478bd9Sstevel@tonic-gate 
437c478bd9Sstevel@tonic-gate #define	THREAD_REG	%g7		/* pointer to current thread data */
447c478bd9Sstevel@tonic-gate 
457c478bd9Sstevel@tonic-gate /*
467c478bd9Sstevel@tonic-gate  * Get the processor implementation from the version register.
477c478bd9Sstevel@tonic-gate  */
487c478bd9Sstevel@tonic-gate #define	GET_CPU_IMPL(out)		\
497c478bd9Sstevel@tonic-gate 	rdpr	%ver,	out;		\
507c478bd9Sstevel@tonic-gate 	srlx	out, 32, out;		\
517c478bd9Sstevel@tonic-gate 	sll	out, 16, out;		\
527c478bd9Sstevel@tonic-gate 	srl	out, 16, out;
537c478bd9Sstevel@tonic-gate 
547c478bd9Sstevel@tonic-gate #ifdef	_STARFIRE
557c478bd9Sstevel@tonic-gate /*
567c478bd9Sstevel@tonic-gate  * CPU_INDEX(r, scr)
577c478bd9Sstevel@tonic-gate  * Returns cpu id in r.
587c478bd9Sstevel@tonic-gate  * On Starfire, this is read from the Port Controller's Port ID
597c478bd9Sstevel@tonic-gate  * register in local space.
607c478bd9Sstevel@tonic-gate  *
617c478bd9Sstevel@tonic-gate  * Need to load the 64 bit address of the PC's PortID reg
627c478bd9Sstevel@tonic-gate  * using only one register. Kludge the 41 bits address constant to
637c478bd9Sstevel@tonic-gate  * be 32bits by shifting it 12 bits to the right first.
647c478bd9Sstevel@tonic-gate  */
657c478bd9Sstevel@tonic-gate #define	LOCAL_PC_PORTID_ADDR_SRL12 0x1FFF4000
667c478bd9Sstevel@tonic-gate #define	PC_PORT_ID 0xD0
677c478bd9Sstevel@tonic-gate 
687c478bd9Sstevel@tonic-gate #define	CPU_INDEX(r, scr)			\
697c478bd9Sstevel@tonic-gate 	rdpr	%pstate, scr;			\
707c478bd9Sstevel@tonic-gate 	andn	scr, PSTATE_IE | PSTATE_AM, r;	\
717c478bd9Sstevel@tonic-gate 	wrpr	r, 0, %pstate;			\
727c478bd9Sstevel@tonic-gate 	set	LOCAL_PC_PORTID_ADDR_SRL12, r;  \
737c478bd9Sstevel@tonic-gate 	sllx    r, 12, r;                       \
747c478bd9Sstevel@tonic-gate 	or	r, PC_PORT_ID, r;		\
757c478bd9Sstevel@tonic-gate 	lduwa	[r]ASI_IO, r;			\
767c478bd9Sstevel@tonic-gate 	wrpr	scr, 0, %pstate
777c478bd9Sstevel@tonic-gate 
7825cf1a30Sjl #elif	defined(_OPL)
7925cf1a30Sjl /*
8025cf1a30Sjl  * For OPL platform, we get CPU_INDEX from ASI_EIDR.
8125cf1a30Sjl  */
8225cf1a30Sjl #define	CPU_INDEX(r, scr)		\
8325cf1a30Sjl 	ldxa	[%g0]ASI_EIDR, r;	\
8425cf1a30Sjl 	and	r, 0xfff, r
8525cf1a30Sjl 
8625cf1a30Sjl 
877c478bd9Sstevel@tonic-gate #else /* _STARFIRE */
887c478bd9Sstevel@tonic-gate 
897c478bd9Sstevel@tonic-gate /*
907c478bd9Sstevel@tonic-gate  * UPA supports up to 32 devices while Safari supports up to
917c478bd9Sstevel@tonic-gate  * 1024 devices (utilizing the SSM protocol). Based upon the
927c478bd9Sstevel@tonic-gate  * value of NCPU, a 5- or 10-bit mask will be needed for
937c478bd9Sstevel@tonic-gate  * extracting the cpu id.
947c478bd9Sstevel@tonic-gate  */
957c478bd9Sstevel@tonic-gate #if NCPU > 32
967c478bd9Sstevel@tonic-gate #define	CPU_MASK	0x3ff
977c478bd9Sstevel@tonic-gate #else
987c478bd9Sstevel@tonic-gate #define	CPU_MASK	0x1f
997c478bd9Sstevel@tonic-gate #endif	/* NCPU > 32 */
1007c478bd9Sstevel@tonic-gate 
1017c478bd9Sstevel@tonic-gate /*
1027c478bd9Sstevel@tonic-gate  * CPU_INDEX(r, scr)
1037c478bd9Sstevel@tonic-gate  * Returns cpu id in r.
1047c478bd9Sstevel@tonic-gate  * For UPA based systems, the cpu id corresponds to the mid field in
1057c478bd9Sstevel@tonic-gate  * the UPA config register. For Safari based machines, the cpu id
1067c478bd9Sstevel@tonic-gate  * corresponds to the aid field in the Safari config register.
1077c478bd9Sstevel@tonic-gate  *
1087c478bd9Sstevel@tonic-gate  * XXX - scr reg is not used here.
1097c478bd9Sstevel@tonic-gate  */
1107c478bd9Sstevel@tonic-gate #define	CPU_INDEX(r, scr)		\
1117c478bd9Sstevel@tonic-gate 	ldxa	[%g0]ASI_UPA_CONFIG, r;	\
1127c478bd9Sstevel@tonic-gate 	srlx	r, 17, r;		\
1137c478bd9Sstevel@tonic-gate 	and	r, CPU_MASK, r
1147c478bd9Sstevel@tonic-gate 
1157c478bd9Sstevel@tonic-gate #endif	/* _STARFIRE */
1167c478bd9Sstevel@tonic-gate 
1177c478bd9Sstevel@tonic-gate /*
1187c478bd9Sstevel@tonic-gate  * Given a cpu id extract the appropriate word
1197c478bd9Sstevel@tonic-gate  * in the cpuset mask for this cpu id.
1207c478bd9Sstevel@tonic-gate  */
1217c478bd9Sstevel@tonic-gate #if CPUSET_SIZE > CLONGSIZE
1227c478bd9Sstevel@tonic-gate #define	CPU_INDEXTOSET(base, index, scr)	\
1237c478bd9Sstevel@tonic-gate 	srl	index, BT_ULSHIFT, scr;		\
1247c478bd9Sstevel@tonic-gate 	and	index, BT_ULMASK, index;	\
1257c478bd9Sstevel@tonic-gate 	sll	scr, CLONGSHIFT, scr;		\
1267c478bd9Sstevel@tonic-gate 	add	base, scr, base
1277c478bd9Sstevel@tonic-gate #else
1287c478bd9Sstevel@tonic-gate #define	CPU_INDEXTOSET(base, index, scr)
1297c478bd9Sstevel@tonic-gate #endif	/* CPUSET_SIZE */
1307c478bd9Sstevel@tonic-gate 
1317c478bd9Sstevel@tonic-gate 
1327c478bd9Sstevel@tonic-gate /*
1337c478bd9Sstevel@tonic-gate  * Assembly macro to find address of the current CPU.
1347c478bd9Sstevel@tonic-gate  * Used when coming in from a user trap - cannot use THREAD_REG.
1357c478bd9Sstevel@tonic-gate  * Args are destination register and one scratch register.
1367c478bd9Sstevel@tonic-gate  */
1377c478bd9Sstevel@tonic-gate #define	CPU_ADDR(reg, scr) 		\
1387c478bd9Sstevel@tonic-gate 	.global	cpu;			\
1397c478bd9Sstevel@tonic-gate 	CPU_INDEX(scr, reg);		\
1407c478bd9Sstevel@tonic-gate 	sll	scr, CPTRSHIFT, scr;	\
1417c478bd9Sstevel@tonic-gate 	set	cpu, reg;		\
1427c478bd9Sstevel@tonic-gate 	ldn	[reg + scr], reg
1437c478bd9Sstevel@tonic-gate 
1447c478bd9Sstevel@tonic-gate #define	CINT64SHIFT	3
1457c478bd9Sstevel@tonic-gate 
1467c478bd9Sstevel@tonic-gate /*
1477c478bd9Sstevel@tonic-gate  * Assembly macro to find the physical address of the current CPU.
1487c478bd9Sstevel@tonic-gate  * All memory references using VA must be limited to nucleus
1497c478bd9Sstevel@tonic-gate  * memory to avoid any MMU side effect.
1507c478bd9Sstevel@tonic-gate  */
1517c478bd9Sstevel@tonic-gate #define	CPU_PADDR(reg, scr)				\
1527c478bd9Sstevel@tonic-gate 	.global cpu_pa;					\
1537c478bd9Sstevel@tonic-gate 	CPU_INDEX(scr, reg);				\
1547c478bd9Sstevel@tonic-gate 	sll	scr, CINT64SHIFT, scr;			\
1557c478bd9Sstevel@tonic-gate 	set	cpu_pa, reg;				\
1567c478bd9Sstevel@tonic-gate 	ldx	[reg + scr], reg
1577c478bd9Sstevel@tonic-gate 
1587c478bd9Sstevel@tonic-gate #endif	/* _ASM */
1597c478bd9Sstevel@tonic-gate 
1608f230a59Sbs /*
1618f230a59Sbs  * If a high level trap handler decides to call sys_trap() to execute some
1628f230a59Sbs  * base level code, context and other registers must be set to proper
1638f230a59Sbs  * values to run kernel. This is true for most part of the kernel, except
1648f230a59Sbs  * for user_rtt, a substantial part of which is executed with registers
1658f230a59Sbs  * ready to run user code. The following macro may be used to detect this
1668f230a59Sbs  * condition and handle it. Please note that, in general, we can't restart
1678f230a59Sbs  * arbitrary piece of code running at tl > 0; user_rtt is a special case
1688f230a59Sbs  * that can be handled.
1698f230a59Sbs  *
1708f230a59Sbs  * Entry condition:
1718f230a59Sbs  *
1728f230a59Sbs  * %tl = 2
1738f230a59Sbs  * pstate.ag = 1
1748f230a59Sbs  *
1758f230a59Sbs  * Register usage:
1768f230a59Sbs  *
1778f230a59Sbs  * scr1, scr2 - destroyed
1788f230a59Sbs  * normal %g5 and %g6 - destroyed
1798f230a59Sbs  *
1808f230a59Sbs  */
1818f230a59Sbs /* BEGIN CSTYLED */
1828f230a59Sbs #define	RESET_USER_RTT_REGS(scr1, scr2, label)				\
1838f230a59Sbs 	/*								\
1848f230a59Sbs 	 * do nothing if %tl != 2. this an attempt to stop this		\
1858f230a59Sbs 	 * piece of code from executing more than once before going	\
1868f230a59Sbs 	 * back to TL=0. more specifically, the changes we are doing	\
1878f230a59Sbs 	 * to %wstate, %canrestore and %otherwin can't be done more	\
1888f230a59Sbs 	 * than once before going to TL=0. note that it is okay to	\
1898f230a59Sbs 	 * execute this more than once if we restart at user_rtt and	\
1908f230a59Sbs 	 * come back from there.					\
1918f230a59Sbs 	 */								\
1928f230a59Sbs 	rdpr	%tl, scr1;						\
1938f230a59Sbs 	cmp	scr1, 2;						\
1948f230a59Sbs 	bne,a,pn %xcc, label;						\
1958f230a59Sbs 	nop;								\
1968f230a59Sbs 	/*								\
1978f230a59Sbs 	 * read tstate[2].%tpc. do nothing if it is not			\
1988f230a59Sbs 	 * between rtt_ctx_start and rtt_ctx_end.			\
1998f230a59Sbs 	 */								\
2008f230a59Sbs 	rdpr	%tpc, scr1;						\
2018f230a59Sbs 	set	rtt_ctx_end, scr2;					\
2028f230a59Sbs 	cmp	scr1, scr2;						\
2038f230a59Sbs 	bgu,a,pt %xcc, label;						\
2048f230a59Sbs 	nop;								\
2058f230a59Sbs 	set	rtt_ctx_start, scr2;					\
2068f230a59Sbs 	cmp	scr1, scr2;						\
2078f230a59Sbs 	blu,a,pt %xcc, label;						\
2088f230a59Sbs 	nop;								\
2098f230a59Sbs 	/*								\
2108f230a59Sbs 	 * pickup tstate[2].cwp						\
2118f230a59Sbs 	 */								\
2128f230a59Sbs 	rdpr	%tstate, scr1;						\
2138f230a59Sbs 	and	scr1, TSTATE_CWP, scr1;					\
2148f230a59Sbs 	/*								\
2158f230a59Sbs 	 * set tstate[1].cwp to tstate[2].cwp. fudge			\
2168f230a59Sbs 	 * tstate[1].tpc and tstate[1].tnpc to restart			\
2178f230a59Sbs 	 * user_rtt.							\
2188f230a59Sbs 	 */								\
2198f230a59Sbs 	wrpr	%g0, 1, %tl;						\
2208f230a59Sbs 	set	TSTATE_KERN | TSTATE_IE, scr2;				\
2218f230a59Sbs 	or	scr1, scr2, scr2;					\
2228f230a59Sbs 	wrpr    %g0, scr2, %tstate;					\
2238f230a59Sbs 	set	user_rtt, scr1;						\
2248f230a59Sbs 	wrpr	%g0, scr1, %tpc;					\
2258f230a59Sbs 	add	scr1, 4, scr1;						\
2268f230a59Sbs 	wrpr	%g0, scr1, %tnpc;					\
2278f230a59Sbs 	/*								\
2288f230a59Sbs 	 * restore %tl							\
2298f230a59Sbs 	 */								\
2308f230a59Sbs 	wrpr	%g0, 2, %tl;						\
2318f230a59Sbs 	/*								\
2328f230a59Sbs 	 * set %wstate							\
2338f230a59Sbs 	 */								\
2348f230a59Sbs 	rdpr	%wstate, scr1;						\
2358f230a59Sbs 	sllx	scr1, WSTATE_SHIFT, scr1;				\
2368f230a59Sbs 	wrpr    scr1, WSTATE_K64, %wstate;				\
2378f230a59Sbs 	/*								\
2388f230a59Sbs 	 * setup window registers					\
2398f230a59Sbs 	 * %cleanwin <-- nwin - 1					\
2408f230a59Sbs 	 * %otherwin <-- %canrestore					\
2418f230a59Sbs 	 * %canrestore <-- 0						\
2428f230a59Sbs 	 */								\
2438f230a59Sbs 	sethi   %hi(nwin_minus_one), scr1;				\
2448f230a59Sbs 	ld	[scr1 + %lo(nwin_minus_one)], scr1;			\
2458f230a59Sbs 	wrpr    %g0, scr1, %cleanwin;					\
2468f230a59Sbs 	rdpr	%canrestore, scr1;					\
2478f230a59Sbs 	wrpr	%g0, scr1, %otherwin;					\
2488f230a59Sbs 	wrpr	%g0, 0, %canrestore;					\
2498f230a59Sbs 	/*								\
2508f230a59Sbs 	 * set THREAD_REG, as we have restored user			\
2518f230a59Sbs 	 * registers in user_rtt. we trash %g5 and %g6			\
2528f230a59Sbs 	 * in the process.						\
2538f230a59Sbs 	 */								\
2548f230a59Sbs 	rdpr    %pstate, scr1;						\
2558f230a59Sbs 	wrpr	scr1, PSTATE_AG, %pstate;				\
2568f230a59Sbs 	/*								\
2578f230a59Sbs 	 * using normal globals now					\
2588f230a59Sbs 	 */								\
2598f230a59Sbs 	CPU_ADDR(%g5, %g6);						\
2608f230a59Sbs 	ldn	[%g5 + CPU_THREAD], %g6;				\
2618f230a59Sbs 	mov	%g6, THREAD_REG;					\
2628f230a59Sbs 	rdpr	%pstate, %g5;						\
2638f230a59Sbs 	wrpr	%g5, PSTATE_AG, %pstate;				\
2648f230a59Sbs 	/*								\
2658f230a59Sbs 	 * back to alternate globals.					\
2668f230a59Sbs 	 * set PCONTEXT to run kernel.					\
267*febcc4a5Sjimand 	 * A demap of I/DTLB is required if the nucleus bits differ	\
268*febcc4a5Sjimand 	 * from kcontextreg.						\
2698f230a59Sbs 	 */								\
2708f230a59Sbs 	mov	MMU_PCONTEXT, scr1;					\
2718f230a59Sbs 	sethi	%hi(kcontextreg), scr2;					\
2728f230a59Sbs 	ldx     [scr2 + %lo(kcontextreg)], scr2;			\
273*febcc4a5Sjimand 	ldxa	[scr1]ASI_MMU_CTX, %g5;					\
274*febcc4a5Sjimand 	xor	scr2, %g5, %g5;						\
275*febcc4a5Sjimand 	srlx	%g5, CTXREG_NEXT_SHIFT, %g5;				\
276*febcc4a5Sjimand 	/*								\
277*febcc4a5Sjimand 	 * If N_pgsz0/1 changed, need to demap.				\
278*febcc4a5Sjimand 	 */								\
279*febcc4a5Sjimand 	brz	%g5, 1f;						\
280*febcc4a5Sjimand 	sethi   %hi(FLUSH_ADDR), %g5;					\
281*febcc4a5Sjimand 	mov	DEMAP_ALL_TYPE, %g6;					\
282*febcc4a5Sjimand 	stxa	%g0, [%g6]ASI_DTLB_DEMAP;				\
283*febcc4a5Sjimand 	stxa	%g0, [%g6]ASI_ITLB_DEMAP;				\
284*febcc4a5Sjimand 1:									\
2858f230a59Sbs 	stxa    scr2, [scr1]ASI_MMU_CTX;				\
286*febcc4a5Sjimand 	flush	%g5;
2878f230a59Sbs 
2888f230a59Sbs /* END CSTYLED */
2898f230a59Sbs 
2907c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
2917c478bd9Sstevel@tonic-gate }
2927c478bd9Sstevel@tonic-gate #endif
2937c478bd9Sstevel@tonic-gate 
2947c478bd9Sstevel@tonic-gate #endif	/* _SYS_MACHTHREAD_H */
295