xref: /titanic_44/usr/src/uts/sun4u/sys/machthread.h (revision 8f230a59881a2147e93577a667f8569f98dc7a28)
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
57c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate  * with the License.
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate  * and limitations under the License.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * CDDL HEADER END
217c478bd9Sstevel@tonic-gate  */
227c478bd9Sstevel@tonic-gate /*
23*8f230a59Sbs21162  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate #ifndef	_SYS_MACHTHREAD_H
287c478bd9Sstevel@tonic-gate #define	_SYS_MACHTHREAD_H
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
317c478bd9Sstevel@tonic-gate 
327c478bd9Sstevel@tonic-gate #include <sys/asi.h>
337c478bd9Sstevel@tonic-gate #include <sys/sun4asi.h>
347c478bd9Sstevel@tonic-gate #include <sys/machasi.h>
357c478bd9Sstevel@tonic-gate #include <sys/bitmap.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 
787c478bd9Sstevel@tonic-gate #else /* _STARFIRE */
797c478bd9Sstevel@tonic-gate 
807c478bd9Sstevel@tonic-gate /*
817c478bd9Sstevel@tonic-gate  * UPA supports up to 32 devices while Safari supports up to
827c478bd9Sstevel@tonic-gate  * 1024 devices (utilizing the SSM protocol). Based upon the
837c478bd9Sstevel@tonic-gate  * value of NCPU, a 5- or 10-bit mask will be needed for
847c478bd9Sstevel@tonic-gate  * extracting the cpu id.
857c478bd9Sstevel@tonic-gate  */
867c478bd9Sstevel@tonic-gate #if NCPU > 32
877c478bd9Sstevel@tonic-gate #define	CPU_MASK	0x3ff
887c478bd9Sstevel@tonic-gate #else
897c478bd9Sstevel@tonic-gate #define	CPU_MASK	0x1f
907c478bd9Sstevel@tonic-gate #endif	/* NCPU > 32 */
917c478bd9Sstevel@tonic-gate 
927c478bd9Sstevel@tonic-gate /*
937c478bd9Sstevel@tonic-gate  * CPU_INDEX(r, scr)
947c478bd9Sstevel@tonic-gate  * Returns cpu id in r.
957c478bd9Sstevel@tonic-gate  * For UPA based systems, the cpu id corresponds to the mid field in
967c478bd9Sstevel@tonic-gate  * the UPA config register. For Safari based machines, the cpu id
977c478bd9Sstevel@tonic-gate  * corresponds to the aid field in the Safari config register.
987c478bd9Sstevel@tonic-gate  *
997c478bd9Sstevel@tonic-gate  * XXX - scr reg is not used here.
1007c478bd9Sstevel@tonic-gate  */
1017c478bd9Sstevel@tonic-gate #define	CPU_INDEX(r, scr)		\
1027c478bd9Sstevel@tonic-gate 	ldxa	[%g0]ASI_UPA_CONFIG, r;	\
1037c478bd9Sstevel@tonic-gate 	srlx	r, 17, r;		\
1047c478bd9Sstevel@tonic-gate 	and	r, CPU_MASK, r
1057c478bd9Sstevel@tonic-gate 
1067c478bd9Sstevel@tonic-gate #endif	/* _STARFIRE */
1077c478bd9Sstevel@tonic-gate 
1087c478bd9Sstevel@tonic-gate /*
1097c478bd9Sstevel@tonic-gate  * Given a cpu id extract the appropriate word
1107c478bd9Sstevel@tonic-gate  * in the cpuset mask for this cpu id.
1117c478bd9Sstevel@tonic-gate  */
1127c478bd9Sstevel@tonic-gate #if CPUSET_SIZE > CLONGSIZE
1137c478bd9Sstevel@tonic-gate #define	CPU_INDEXTOSET(base, index, scr)	\
1147c478bd9Sstevel@tonic-gate 	srl	index, BT_ULSHIFT, scr;		\
1157c478bd9Sstevel@tonic-gate 	and	index, BT_ULMASK, index;	\
1167c478bd9Sstevel@tonic-gate 	sll	scr, CLONGSHIFT, scr;		\
1177c478bd9Sstevel@tonic-gate 	add	base, scr, base
1187c478bd9Sstevel@tonic-gate #else
1197c478bd9Sstevel@tonic-gate #define	CPU_INDEXTOSET(base, index, scr)
1207c478bd9Sstevel@tonic-gate #endif	/* CPUSET_SIZE */
1217c478bd9Sstevel@tonic-gate 
1227c478bd9Sstevel@tonic-gate 
1237c478bd9Sstevel@tonic-gate /*
1247c478bd9Sstevel@tonic-gate  * Assembly macro to find address of the current CPU.
1257c478bd9Sstevel@tonic-gate  * Used when coming in from a user trap - cannot use THREAD_REG.
1267c478bd9Sstevel@tonic-gate  * Args are destination register and one scratch register.
1277c478bd9Sstevel@tonic-gate  */
1287c478bd9Sstevel@tonic-gate #define	CPU_ADDR(reg, scr) 		\
1297c478bd9Sstevel@tonic-gate 	.global	cpu;			\
1307c478bd9Sstevel@tonic-gate 	CPU_INDEX(scr, reg);		\
1317c478bd9Sstevel@tonic-gate 	sll	scr, CPTRSHIFT, scr;	\
1327c478bd9Sstevel@tonic-gate 	set	cpu, reg;		\
1337c478bd9Sstevel@tonic-gate 	ldn	[reg + scr], reg
1347c478bd9Sstevel@tonic-gate 
1357c478bd9Sstevel@tonic-gate #define	CINT64SHIFT	3
1367c478bd9Sstevel@tonic-gate 
1377c478bd9Sstevel@tonic-gate /*
1387c478bd9Sstevel@tonic-gate  * Assembly macro to find the physical address of the current CPU.
1397c478bd9Sstevel@tonic-gate  * All memory references using VA must be limited to nucleus
1407c478bd9Sstevel@tonic-gate  * memory to avoid any MMU side effect.
1417c478bd9Sstevel@tonic-gate  */
1427c478bd9Sstevel@tonic-gate #define	CPU_PADDR(reg, scr)				\
1437c478bd9Sstevel@tonic-gate 	.global cpu_pa;					\
1447c478bd9Sstevel@tonic-gate 	CPU_INDEX(scr, reg);				\
1457c478bd9Sstevel@tonic-gate 	sll	scr, CINT64SHIFT, scr;			\
1467c478bd9Sstevel@tonic-gate 	set	cpu_pa, reg;				\
1477c478bd9Sstevel@tonic-gate 	ldx	[reg + scr], reg
1487c478bd9Sstevel@tonic-gate 
1497c478bd9Sstevel@tonic-gate #endif	/* _ASM */
1507c478bd9Sstevel@tonic-gate 
151*8f230a59Sbs21162 /*
152*8f230a59Sbs21162  * If a high level trap handler decides to call sys_trap() to execute some
153*8f230a59Sbs21162  * base level code, context and other registers must be set to proper
154*8f230a59Sbs21162  * values to run kernel. This is true for most part of the kernel, except
155*8f230a59Sbs21162  * for user_rtt, a substantial part of which is executed with registers
156*8f230a59Sbs21162  * ready to run user code. The following macro may be used to detect this
157*8f230a59Sbs21162  * condition and handle it. Please note that, in general, we can't restart
158*8f230a59Sbs21162  * arbitrary piece of code running at tl > 0; user_rtt is a special case
159*8f230a59Sbs21162  * that can be handled.
160*8f230a59Sbs21162  *
161*8f230a59Sbs21162  * Entry condition:
162*8f230a59Sbs21162  *
163*8f230a59Sbs21162  * %tl = 2
164*8f230a59Sbs21162  * pstate.ag = 1
165*8f230a59Sbs21162  *
166*8f230a59Sbs21162  * Register usage:
167*8f230a59Sbs21162  *
168*8f230a59Sbs21162  * scr1, scr2 - destroyed
169*8f230a59Sbs21162  * normal %g5 and %g6 - destroyed
170*8f230a59Sbs21162  *
171*8f230a59Sbs21162  */
172*8f230a59Sbs21162 /* BEGIN CSTYLED */
173*8f230a59Sbs21162 #define	RESET_USER_RTT_REGS(scr1, scr2, label)				\
174*8f230a59Sbs21162 	/*								\
175*8f230a59Sbs21162 	 * do nothing if %tl != 2. this an attempt to stop this		\
176*8f230a59Sbs21162 	 * piece of code from executing more than once before going	\
177*8f230a59Sbs21162 	 * back to TL=0. more specifically, the changes we are doing	\
178*8f230a59Sbs21162 	 * to %wstate, %canrestore and %otherwin can't be done more	\
179*8f230a59Sbs21162 	 * than once before going to TL=0. note that it is okay to	\
180*8f230a59Sbs21162 	 * execute this more than once if we restart at user_rtt and	\
181*8f230a59Sbs21162 	 * come back from there.					\
182*8f230a59Sbs21162 	 */								\
183*8f230a59Sbs21162 	rdpr	%tl, scr1;						\
184*8f230a59Sbs21162 	cmp	scr1, 2;						\
185*8f230a59Sbs21162 	bne,a,pn %xcc, label;						\
186*8f230a59Sbs21162 	nop;								\
187*8f230a59Sbs21162 	/*								\
188*8f230a59Sbs21162 	 * read tstate[2].%tpc. do nothing if it is not			\
189*8f230a59Sbs21162 	 * between rtt_ctx_start and rtt_ctx_end.			\
190*8f230a59Sbs21162 	 */								\
191*8f230a59Sbs21162 	rdpr	%tpc, scr1;						\
192*8f230a59Sbs21162 	set	rtt_ctx_end, scr2;					\
193*8f230a59Sbs21162 	cmp	scr1, scr2;						\
194*8f230a59Sbs21162 	bgu,a,pt %xcc, label;						\
195*8f230a59Sbs21162 	nop;								\
196*8f230a59Sbs21162 	set	rtt_ctx_start, scr2;					\
197*8f230a59Sbs21162 	cmp	scr1, scr2;						\
198*8f230a59Sbs21162 	blu,a,pt %xcc, label;						\
199*8f230a59Sbs21162 	nop;								\
200*8f230a59Sbs21162 	/*								\
201*8f230a59Sbs21162 	 * pickup tstate[2].cwp						\
202*8f230a59Sbs21162 	 */								\
203*8f230a59Sbs21162 	rdpr	%tstate, scr1;						\
204*8f230a59Sbs21162 	and	scr1, TSTATE_CWP, scr1;					\
205*8f230a59Sbs21162 	/*								\
206*8f230a59Sbs21162 	 * set tstate[1].cwp to tstate[2].cwp. fudge			\
207*8f230a59Sbs21162 	 * tstate[1].tpc and tstate[1].tnpc to restart			\
208*8f230a59Sbs21162 	 * user_rtt.							\
209*8f230a59Sbs21162 	 */								\
210*8f230a59Sbs21162 	wrpr	%g0, 1, %tl;						\
211*8f230a59Sbs21162 	set	TSTATE_KERN | TSTATE_IE, scr2;				\
212*8f230a59Sbs21162 	or	scr1, scr2, scr2;					\
213*8f230a59Sbs21162 	wrpr    %g0, scr2, %tstate;					\
214*8f230a59Sbs21162 	set	user_rtt, scr1;						\
215*8f230a59Sbs21162 	wrpr	%g0, scr1, %tpc;					\
216*8f230a59Sbs21162 	add	scr1, 4, scr1;						\
217*8f230a59Sbs21162 	wrpr	%g0, scr1, %tnpc;					\
218*8f230a59Sbs21162 	/*								\
219*8f230a59Sbs21162 	 * restore %tl							\
220*8f230a59Sbs21162 	 */								\
221*8f230a59Sbs21162 	wrpr	%g0, 2, %tl;						\
222*8f230a59Sbs21162 	/*								\
223*8f230a59Sbs21162 	 * set %wstate							\
224*8f230a59Sbs21162 	 */								\
225*8f230a59Sbs21162 	rdpr	%wstate, scr1;						\
226*8f230a59Sbs21162 	sllx	scr1, WSTATE_SHIFT, scr1;				\
227*8f230a59Sbs21162 	wrpr    scr1, WSTATE_K64, %wstate;				\
228*8f230a59Sbs21162 	/*								\
229*8f230a59Sbs21162 	 * setup window registers					\
230*8f230a59Sbs21162 	 * %cleanwin <-- nwin - 1					\
231*8f230a59Sbs21162 	 * %otherwin <-- %canrestore					\
232*8f230a59Sbs21162 	 * %canrestore <-- 0						\
233*8f230a59Sbs21162 	 */								\
234*8f230a59Sbs21162 	sethi   %hi(nwin_minus_one), scr1;				\
235*8f230a59Sbs21162 	ld	[scr1 + %lo(nwin_minus_one)], scr1;			\
236*8f230a59Sbs21162 	wrpr    %g0, scr1, %cleanwin;					\
237*8f230a59Sbs21162 	rdpr	%canrestore, scr1;					\
238*8f230a59Sbs21162 	wrpr	%g0, scr1, %otherwin;					\
239*8f230a59Sbs21162 	wrpr	%g0, 0, %canrestore;					\
240*8f230a59Sbs21162 	/*								\
241*8f230a59Sbs21162 	 * set THREAD_REG, as we have restored user			\
242*8f230a59Sbs21162 	 * registers in user_rtt. we trash %g5 and %g6			\
243*8f230a59Sbs21162 	 * in the process.						\
244*8f230a59Sbs21162 	 */								\
245*8f230a59Sbs21162 	rdpr    %pstate, scr1;						\
246*8f230a59Sbs21162 	wrpr	scr1, PSTATE_AG, %pstate;				\
247*8f230a59Sbs21162 	/*								\
248*8f230a59Sbs21162 	 * using normal globals now					\
249*8f230a59Sbs21162 	 */								\
250*8f230a59Sbs21162 	CPU_ADDR(%g5, %g6);						\
251*8f230a59Sbs21162 	ldn	[%g5 + CPU_THREAD], %g6;				\
252*8f230a59Sbs21162 	mov	%g6, THREAD_REG;					\
253*8f230a59Sbs21162 	rdpr	%pstate, %g5;						\
254*8f230a59Sbs21162 	wrpr	%g5, PSTATE_AG, %pstate;				\
255*8f230a59Sbs21162 	/*								\
256*8f230a59Sbs21162 	 * back to alternate globals.					\
257*8f230a59Sbs21162 	 * set PCONTEXT to run kernel.					\
258*8f230a59Sbs21162 	 * no need to demap I/DTLB as we				\
259*8f230a59Sbs21162 	 * never went back to user mode.				\
260*8f230a59Sbs21162 	 */								\
261*8f230a59Sbs21162 	mov	MMU_PCONTEXT, scr1;					\
262*8f230a59Sbs21162 	sethi	%hi(kcontextreg), scr2;					\
263*8f230a59Sbs21162 	ldx     [scr2 + %lo(kcontextreg)], scr2;			\
264*8f230a59Sbs21162 	stxa    scr2, [scr1]ASI_MMU_CTX;				\
265*8f230a59Sbs21162 	sethi   %hi(FLUSH_ADDR), scr1;					\
266*8f230a59Sbs21162 	flush	scr1;
267*8f230a59Sbs21162 
268*8f230a59Sbs21162 /* END CSTYLED */
269*8f230a59Sbs21162 
2707c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
2717c478bd9Sstevel@tonic-gate }
2727c478bd9Sstevel@tonic-gate #endif
2737c478bd9Sstevel@tonic-gate 
2747c478bd9Sstevel@tonic-gate #endif	/* _SYS_MACHTHREAD_H */
275