xref: /titanic_52/usr/src/uts/sparc/v9/ml/syscall_trap.s (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License").  You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22/*
23 * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27#pragma ident	"%Z%%M%	%I%	%E% SMI"
28
29/*
30 * System call trap handler.
31 */
32#include <sys/asm_linkage.h>
33#include <sys/machpcb.h>
34#include <sys/machthread.h>
35#include <sys/syscall.h>
36#include <sys/trap.h>
37#include <sys/machtrap.h>
38#include <sys/pcb.h>
39#include <sys/machparam.h>
40
41#if !defined(lint) && !defined(__lint)
42#include "assym.h"
43#endif
44
45#ifdef TRAPTRACE
46#include <sys/traptrace.h>
47#endif /* TRAPTRACE */
48
49#if defined(lint) || defined(__lint)
50
51/*ARGSUSED*/
52void
53syscall_trap(struct regs *rp)	/* for tags only; not called from C */
54{}
55
56#else /* lint */
57
58#if (1 << SYSENT_SHIFT) != SYSENT_SIZE
59#error	"SYSENT_SHIFT does not correspond to size of sysent structure"
60#endif
61
62/*
63 * Native System call trap handler.
64 *
65 * We branch here from sys_trap when a 64-bit system call occurs.
66 *
67 * Entry:
68 *	%o0 = regs
69 *
70 * Usage:
71 *	%l0 = saved return address
72 *	%l1 = saved regs
73 *	%l2 = lwp
74 */
75	ENTRY_NP(syscall_trap)
76	ldn	[THREAD_REG + T_CPU], %g1	! get cpu pointer
77	mov	%o7, %l0			! save return addr
78	!
79	! If the trapping thread has the address mask bit set, then it's
80	!   a 32-bit process, and has no business calling 64-bit syscalls.
81	!
82	ldx	[%o0 + TSTATE_OFF], %l1		! saved %tstate.am is that
83	andcc	%l1, TSTATE_AM, %l1		!   of the trapping proc
84	bne,pn	%xcc, _syscall_ill		!
85	mov	%o0, %l1			! save reg pointer
86	mov	%i0, %o0			! copy 1st arg
87	mov	%i1, %o1			! copy 2nd arg
88	ldx	[%g1 + CPU_STATS_SYS_SYSCALL], %g2
89	inc	%g2				! cpu_stats.sys.syscall++
90	stx	%g2, [%g1 + CPU_STATS_SYS_SYSCALL]
91
92	!
93	! Set new state for LWP
94	!
95	ldn	[THREAD_REG + T_LWP], %l2
96	mov	LWP_SYS, %g3
97	mov	%i2, %o2			! copy 3rd arg
98	stb	%g3, [%l2 + LWP_STATE]
99	mov	%i3, %o3			! copy 4th arg
100	ldx	[%l2 + LWP_RU_SYSC], %g2	! pesky statistics
101	mov	%i4, %o4			! copy 5th arg
102	addx	%g2, 1, %g2
103	stx	%g2, [%l2 + LWP_RU_SYSC]
104	mov	%i5, %o5			! copy 6th arg
105	! args for direct syscalls now set up
106
107#ifdef TRAPTRACE
108	!
109	! make trap trace entry - helps in debugging
110	!
111	rdpr	%pstate, %l3
112	andn	%l3, PSTATE_IE | PSTATE_AM, %g3
113	wrpr	%g0, %g3, %pstate		! disable interrupt
114	TRACE_PTR(%g3, %g2)			! get trace pointer
115	GET_TRACE_TICK(%g1)
116	stxa	%g1, [%g3 + TRAP_ENT_TICK]%asi
117	ldx	[%l1 + G1_OFF], %g1		! get syscall code
118	TRACE_SAVE_TL_VAL(%g3, %g1)
119	TRACE_SAVE_GL_VAL(%g3, %g0)
120	set	TT_SC_ENTR, %g2
121	stha	%g2, [%g3 + TRAP_ENT_TT]%asi
122	stxa	%g7, [%g3 + TRAP_ENT_TSTATE]%asi ! save thread in tstate space
123	stna	%sp, [%g3 + TRAP_ENT_SP]%asi
124	stna	%o0, [%g3 + TRAP_ENT_F1]%asi
125	stna	%o1, [%g3 + TRAP_ENT_F2]%asi
126	stna	%o2, [%g3 + TRAP_ENT_F3]%asi
127	stna	%o3, [%g3 + TRAP_ENT_F4]%asi
128	stna	%o4, [%g3 + TRAP_ENT_TPC]%asi
129	stna	%o5, [%g3 + TRAP_ENT_TR]%asi
130	TRACE_NEXT(%g3, %g2, %g1)		! set new trace pointer
131	wrpr	%g0, %l3, %pstate		! enable interrupt
132#endif /* TRAPTRACE */
133
134	!
135	! Test for pre-system-call handling
136	!
137	ldub	[THREAD_REG + T_PRE_SYS], %g3	! pre-syscall proc?
138#ifdef SYSCALLTRACE
139	sethi	%hi(syscalltrace), %g4
140	ld	[%g4 + %lo(syscalltrace)], %g4
141	orcc	%g3, %g4, %g0			! pre_syscall OR syscalltrace?
142#else
143	tst	%g3				! is pre_syscall flag set?
144#endif /* SYSCALLTRACE */
145
146	bnz,pn	%icc, _syscall_pre
147	nop
148
149	! Fast path invocation of new_mstate
150
151	mov	LMS_USER, %o0
152	call	syscall_mstate
153	mov	LMS_SYSTEM, %o1
154
155	ldx	[%l1 + O0_OFF], %o0		! restore %o0
156	ldx	[%l1 + O1_OFF], %o1		! restore %o1
157	ldx	[%l1 + O2_OFF], %o2
158	ldx     [%l1 + O3_OFF], %o3
159	ldx     [%l1 + O4_OFF], %o4
160	ldx	[%l1 + O5_OFF], %o5
161
162	! lwp_arg now set up
1633:
164	!
165	! Call the handler.  The %o's and lwp_arg have been set up.
166	!
167	ldx	[%l1 + G1_OFF], %g1		! get code
168	set	sysent, %g3			! load address of vector table
169	cmp	%g1, NSYSCALL			! check range
170	sth	%g1, [THREAD_REG + T_SYSNUM]	! save syscall code
171	bgeu,pn	%ncc, _syscall_ill
172	  sll	%g1, SYSENT_SHIFT, %g4			! delay - get index
173	add	%g3, %g4, %l4
174	ldn	[%l4 + SY_CALLC], %g3		! load system call handler
175
176	call	%g3				! call system call handler
177	  nop
178	!
179	! If handler returns two ints, then we need to split the 64-bit
180	! return value in %o0 into %o0 and %o1
181	!
182	lduh	[%l4 + SY_FLAGS], %l4		! load sy_flags
183	andcc	%l4, SE_32RVAL2, %g0		! check for 2 x 32-bit
184	bz,pt	%xcc, 5f
185	  nop
186	srl	%o0, 0, %o1			! lower 32-bits into %o1
187	srlx	%o0, 32, %o0			! upper 32-bits into %o0
1885:
189
190#ifdef TRAPTRACE
191	!
192	! make trap trace entry for return - helps in debugging
193	!
194	rdpr	%pstate, %g5
195	andn	%g5, PSTATE_IE | PSTATE_AM, %g4
196	wrpr	%g0, %g4, %pstate		! disable interrupt
197	TRACE_PTR(%g4, %g2)			! get trace pointer
198	GET_TRACE_TICK(%g2)
199	stxa	%g2, [%g4 + TRAP_ENT_TICK]%asi
200	lduh	[THREAD_REG + T_SYSNUM], %g2
201	TRACE_SAVE_TL_VAL(%g4, %g2)
202	TRACE_SAVE_GL_VAL(%g4, %g0)
203	mov	TT_SC_RET, %g2			! system call return code
204	stha	%g2, [%g4 + TRAP_ENT_TT]%asi
205	ldn	[%l1 + nPC_OFF], %g2		! get saved npc (new pc)
206	stna	%g2, [%g4 + TRAP_ENT_TPC]%asi
207	ldx	[%l1 + TSTATE_OFF], %g2		! get saved tstate
208	stxa	%g2, [%g4 + TRAP_ENT_TSTATE]%asi
209	stna	%sp, [%g4 + TRAP_ENT_SP]%asi
210	stna	THREAD_REG, [%g4 + TRAP_ENT_TR]%asi
211	stna	%o0, [%g4 + TRAP_ENT_F1]%asi
212	stna	%o1, [%g4 + TRAP_ENT_F2]%asi
213	stna	%g0, [%g4 + TRAP_ENT_F3]%asi
214	stna	%g0, [%g4 + TRAP_ENT_F4]%asi
215	TRACE_NEXT(%g4, %g2, %g3)		! set new trace pointer
216	wrpr	%g0, %g5, %pstate		! enable interrupt
217#endif /* TRAPTRACE */
218	!
219	! Check for post-syscall processing.
220	! This tests all members of the union containing t_astflag, t_post_sys,
221	! and t_sig_check with one test.
222	!
223	ld	[THREAD_REG + T_POST_SYS_AST], %g1
224#ifdef SYSCALLTRACE
225	sethi	%hi(syscalltrace), %g4
226	ld	[%g4 + %lo(syscalltrace)], %g4
227	orcc	%g4, %g1, %g0			! OR in syscalltrace
228#else
229	tst	%g1				! need post-processing?
230#endif /* SYSCALLTRACE */
231	bnz,pn	%icc, _syscall_post		! yes - post_syscall or AST set
232	mov	LWP_USER, %g1
233	stb	%g1, [%l2 + LWP_STATE]		! set lwp_state
234	stx	%o0, [%l1 + O0_OFF]		! set rp->r_o0
235	stx	%o1, [%l1 + O1_OFF]		! set rp->r_o1
236	clrh	[THREAD_REG + T_SYSNUM]		! clear syscall code
237	ldx	[%l1 + TSTATE_OFF], %g1		! get saved tstate
238	ldn	[%l1 + nPC_OFF], %g2		! get saved npc (new pc)
239	mov	CCR_IC, %g3
240	sllx	%g3, TSTATE_CCR_SHIFT, %g3
241	add	%g2, 4, %g4			! calc new npc
242	andn	%g1, %g3, %g1			! clear carry bit for no error
243	stn	%g2, [%l1 + PC_OFF]
244	stn	%g4, [%l1 + nPC_OFF]
245	stx	%g1, [%l1 + TSTATE_OFF]
246
247	! Switch mstate back on the way out
248
249	mov	LMS_SYSTEM, %o0
250	call	syscall_mstate
251	mov	LMS_USER, %o1
252	jmp	%l0 + 8
253	 nop
254
255_syscall_pre:
256	ldx	[%l1 + G1_OFF], %g1
257	call	pre_syscall			! abort = pre_syscall(arg0)
258	sth	%g1, [THREAD_REG + T_SYSNUM]
259
260	brnz,pn	%o0, _syscall_post		! did it abort?
261	nop
262	ldx	[%l1 + O0_OFF], %o0		! reload args
263	ldx	[%l1 + O1_OFF], %o1
264	ldx	[%l1 + O2_OFF], %o2
265	ldx	[%l1 + O3_OFF], %o3
266	ldx	[%l1 + O4_OFF], %o4
267	ba,pt	%xcc, 3b
268	ldx	[%l1 + O5_OFF], %o5
269
270	!
271	! Floating-point trap was pending at start of system call.
272	! Here with:
273	!	%l3 = mpcb_flags
274	!
275_syscall_fp:
276	andn	%l3, FP_TRAPPED, %l3
277	st	%l3, [%sp + STACK_BIAS + MPCB_FLAGS] 	! clear FP_TRAPPED
278	jmp	%l0 + 8				! return to user_rtt
279	clrh	[THREAD_REG + T_SYSNUM]		! clear syscall code
280
281	!
282	! illegal system call - syscall number out of range
283	!
284_syscall_ill:
285	call	nosys
286	nop
287	!
288	! Post-syscall with special processing needed.
289	!
290_syscall_post:
291	call	post_syscall			! post_syscall(rvals)
292	nop
293	jmp	%l0 + 8				! return to user_rtt
294	nop
295	SET_SIZE(syscall_trap)
296#endif	/* lint */
297
298#if defined(lint) || defined(__lint)
299
300void
301syscall_trap32(void)	/* for tags only - trap handler - not called from C */
302{}
303
304#else /* lint */
305
306/*
307 * System call trap handler for ILP32 processes.
308 *
309 * We branch here from sys_trap when a system call occurs.
310 *
311 * Entry:
312 *	%o0 = regs
313 *
314 * Usage:
315 *	%l0 = saved return address
316 *	%l1 = saved regs
317 *	%l2 = lwp
318 */
319	ENTRY_NP(syscall_trap32)
320	ldx	[THREAD_REG + T_CPU], %g1	! get cpu pointer
321	mov	%o7, %l0			! save return addr
322
323	!
324	! If the trapping thread has the address mask bit clear, then it's
325	!   a 64-bit process, and has no business calling 32-bit syscalls.
326	!
327	ldx	[%o0 + TSTATE_OFF], %l1		! saved %tstate.am is that
328	andcc	%l1, TSTATE_AM, %l1		!   of the trapping proc
329	be,pn	%xcc, _syscall_ill32		!
330	  mov	%o0, %l1			! save reg pointer
331	srl	%i0, 0, %o0			! copy 1st arg, clear high bits
332	srl	%i1, 0, %o1			! copy 2nd arg, clear high bits
333	ldx	[%g1 + CPU_STATS_SYS_SYSCALL], %g2
334	inc	%g2				! cpu_stats.sys.syscall++
335	stx	%g2, [%g1 + CPU_STATS_SYS_SYSCALL]
336
337	!
338	! Set new state for LWP
339	!
340	ldx	[THREAD_REG + T_LWP], %l2
341	mov	LWP_SYS, %g3
342	srl	%i2, 0, %o2			! copy 3rd arg, clear high bits
343	stb	%g3, [%l2 + LWP_STATE]
344	srl	%i3, 0, %o3			! copy 4th arg, clear high bits
345	ldx	[%l2 + LWP_RU_SYSC], %g2	! pesky statistics
346	srl	%i4, 0, %o4			! copy 5th arg, clear high bits
347	addx	%g2, 1, %g2
348	stx	%g2, [%l2 + LWP_RU_SYSC]
349	srl	%i5, 0, %o5			! copy 6th arg, clear high bits
350	! args for direct syscalls now set up
351
352#ifdef TRAPTRACE
353	!
354	! make trap trace entry - helps in debugging
355	!
356	rdpr	%pstate, %l3
357	andn	%l3, PSTATE_IE | PSTATE_AM, %g3
358	wrpr	%g0, %g3, %pstate		! disable interrupt
359	TRACE_PTR(%g3, %g2)			! get trace pointer
360	GET_TRACE_TICK(%g1)
361	stxa	%g1, [%g3 + TRAP_ENT_TICK]%asi
362	ldx	[%l1 + G1_OFF], %g1		! get syscall code
363	TRACE_SAVE_TL_VAL(%g3, %g1)
364	TRACE_SAVE_GL_VAL(%g3, %g0)
365	set	TT_SC_ENTR, %g2
366	stha	%g2, [%g3 + TRAP_ENT_TT]%asi
367	stxa	%g7, [%g3 + TRAP_ENT_TSTATE]%asi ! save thread in tstate space
368	stna	%sp, [%g3 + TRAP_ENT_SP]%asi
369	stna	%o0, [%g3 + TRAP_ENT_F1]%asi
370	stna	%o1, [%g3 + TRAP_ENT_F2]%asi
371	stna	%o2, [%g3 + TRAP_ENT_F3]%asi
372	stna	%o3, [%g3 + TRAP_ENT_F4]%asi
373	stna	%o4, [%g3 + TRAP_ENT_TPC]%asi
374	stna	%o5, [%g3 + TRAP_ENT_TR]%asi
375	TRACE_NEXT(%g3, %g2, %g1)		! set new trace pointer
376	wrpr	%g0, %l3, %pstate		! enable interrupt
377#endif /* TRAPTRACE */
378
379	!
380	! Test for pre-system-call handling
381	!
382	ldub	[THREAD_REG + T_PRE_SYS], %g3	! pre-syscall proc?
383#ifdef SYSCALLTRACE
384	sethi	%hi(syscalltrace), %g4
385	ld	[%g4 + %lo(syscalltrace)], %g4
386	orcc	%g3, %g4, %g0			! pre_syscall OR syscalltrace?
387#else
388	tst	%g3				! is pre_syscall flag set?
389#endif /* SYSCALLTRACE */
390	bnz,pn	%icc, _syscall_pre32		! yes - pre_syscall needed
391	  nop
392
393	! Fast path invocation of new_mstate
394	mov	LMS_USER, %o0
395	call 	syscall_mstate
396	mov	LMS_SYSTEM, %o1
397
398 	lduw	[%l1 + O0_OFF + 4], %o0		! reload 32-bit args
399	lduw	[%l1 + O1_OFF + 4], %o1
400	lduw	[%l1 + O2_OFF + 4], %o2
401	lduw	[%l1 + O3_OFF + 4], %o3
402	lduw	[%l1 + O4_OFF + 4], %o4
403	lduw	[%l1 + O5_OFF + 4], %o5
404
405	! lwp_arg now set up
4063:
407	!
408	! Call the handler.  The %o's have been set up.
409	!
410	lduw	[%l1 + G1_OFF + 4], %g1		! get 32-bit code
411	set	sysent32, %g3			! load address of vector table
412	cmp	%g1, NSYSCALL			! check range
413	sth	%g1, [THREAD_REG + T_SYSNUM]	! save syscall code
414	bgeu,pn	%ncc, _syscall_ill32
415	  sll	%g1, SYSENT_SHIFT, %g4		! delay - get index
416	add	%g3, %g4, %g5			! g5 = addr of sysentry
417	ldx	[%g5 + SY_CALLC], %g3		! load system call handler
418
419	brnz,a,pt %g1, 4f			! check for indir()
420	mov	%g5, %l4			! save addr of sysentry
421	!
422	! Yuck.  If %g1 is zero, that means we're doing a syscall() via the
423	! indirect system call.  That means we have to check the
424	! flags of the targetted system call, not the indirect system call
425	! itself.  See return value handling code below.
426	!
427	set	sysent32, %l4			! load address of vector table
428	cmp	%o0, NSYSCALL			! check range
429	bgeu,pn	%ncc, 4f			! out of range, let C handle it
430	  sll	%o0, SYSENT_SHIFT, %g4		! delay - get index
431	add	%g4, %l4, %l4			! compute & save addr of sysent
4324:
433	call	%g3				! call system call handler
434	nop
435
436	!
437	! If handler returns long long then we need to split the 64 bit
438	! return value in %o0 into %o0 and %o1 for ILP32 clients.
439	!
440	lduh    [%l4 + SY_FLAGS], %g4           ! load sy_flags
441	andcc	%g4, SE_64RVAL | SE_32RVAL2, %g0 ! check for 64-bit return
442	bz,a,pt	%xcc, 5f
443	  srl	%o0, 0, %o0			! 32-bit only
444	srl	%o0, 0, %o1			! lower 32 bits into %o1
445	srlx	%o0, 32, %o0			! upper 32 bits into %o0
4465:
447
448#ifdef TRAPTRACE
449	!
450	! make trap trace entry for return - helps in debugging
451	!
452	rdpr	%pstate, %g5
453	andn	%g5, PSTATE_IE | PSTATE_AM, %g4
454	wrpr	%g0, %g4, %pstate		! disable interrupt
455	TRACE_PTR(%g4, %g2)			! get trace pointer
456	GET_TRACE_TICK(%g2)
457	stxa	%g2, [%g4 + TRAP_ENT_TICK]%asi
458	lduh	[THREAD_REG + T_SYSNUM], %g2
459	TRACE_SAVE_TL_VAL(%g4, %g2)
460	TRACE_SAVE_GL_VAL(%g4, %g0)
461	mov	TT_SC_RET, %g2			! system call return code
462	stha	%g2, [%g4 + TRAP_ENT_TT]%asi
463	ldx	[%l1 + nPC_OFF], %g2		! get saved npc (new pc)
464	stna	%g2, [%g4 + TRAP_ENT_TPC]%asi
465	ldx	[%l1 + TSTATE_OFF], %g2		! get saved tstate
466	stxa	%g2, [%g4 + TRAP_ENT_TSTATE]%asi
467	stna	%sp, [%g4 + TRAP_ENT_SP]%asi
468	stna	THREAD_REG, [%g4 + TRAP_ENT_TR]%asi
469	stna	%o0, [%g4 + TRAP_ENT_F1]%asi
470	stna	%o1, [%g4 + TRAP_ENT_F2]%asi
471	stna	%g0, [%g4 + TRAP_ENT_F3]%asi
472	stna	%g0, [%g4 + TRAP_ENT_F4]%asi
473	TRACE_NEXT(%g4, %g2, %g3)		! set new trace pointer
474	wrpr	%g0, %g5, %pstate		! enable interrupt
475#endif /* TRAPTRACE */
476	!
477	! Check for post-syscall processing.
478	! This tests all members of the union containing t_astflag, t_post_sys,
479	! and t_sig_check with one test.
480	!
481	ld	[THREAD_REG + T_POST_SYS_AST], %g1
482#ifdef SYSCALLTRACE
483	sethi	%hi(syscalltrace), %g4
484	ld	[%g4 + %lo(syscalltrace)], %g4
485	orcc	%g4, %g1, %g0			! OR in syscalltrace
486#else
487	tst	%g1				! need post-processing?
488#endif /* SYSCALLTRACE */
489	bnz,pn	%icc, _syscall_post32		! yes - post_syscall or AST set
490	mov	LWP_USER, %g1
491	stb	%g1, [%l2 + LWP_STATE]		! set lwp_state
492	stx	%o0, [%l1 + O0_OFF]		! set rp->r_o0
493	stx	%o1, [%l1 + O1_OFF]		! set rp->r_o1
494	clrh	[THREAD_REG + T_SYSNUM]		! clear syscall code
495	ldx	[%l1 + TSTATE_OFF], %g1		! get saved tstate
496	ldx	[%l1 + nPC_OFF], %g2		! get saved npc (new pc)
497	mov	CCR_IC, %g3
498	sllx	%g3, TSTATE_CCR_SHIFT, %g3
499	add	%g2, 4, %g4			! calc new npc
500	andn	%g1, %g3, %g1			! clear carry bit for no error
501	stx	%g2, [%l1 + PC_OFF]
502	stx	%g4, [%l1 + nPC_OFF]
503	stx	%g1, [%l1 + TSTATE_OFF]
504
505	! fast path outbound microstate accounting call
506	mov	LMS_SYSTEM, %o0
507	call 	syscall_mstate
508	mov	LMS_USER, %o1
509
510	jmp	%l0 + 8
511	 nop
512
513
514_syscall_pre32:
515	ldx	[%l1 + G1_OFF], %g1
516	call	pre_syscall			! abort = pre_syscall(arg0)
517	sth	%g1, [THREAD_REG + T_SYSNUM]
518
519	brnz,pn	%o0, _syscall_post32		! did it abort?
520	nop
521 	lduw	[%l1 + O0_OFF + 4], %o0		! reload 32-bit args
522	lduw	[%l1 + O1_OFF + 4], %o1
523	lduw	[%l1 + O2_OFF + 4], %o2
524	lduw	[%l1 + O3_OFF + 4], %o3
525	lduw	[%l1 + O4_OFF + 4], %o4
526	ba,pt	%xcc, 3b
527	lduw	[%l1 + O5_OFF + 4], %o5
528
529	!
530	! Floating-point trap was pending at start of system call.
531	! Here with:
532	!	%l3 = mpcb_flags
533	!
534_syscall_fp32:
535	andn	%l3, FP_TRAPPED, %l3
536	st	%l3, [%sp + STACK_BIAS + MPCB_FLAGS] 	! clear FP_TRAPPED
537	jmp	%l0 + 8				! return to user_rtt
538	clrh	[THREAD_REG + T_SYSNUM]		! clear syscall code
539
540	!
541	! illegal system call - syscall number out of range
542	!
543_syscall_ill32:
544	call	nosys
545	nop
546	!
547	! Post-syscall with special processing needed.
548	!
549_syscall_post32:
550	call	post_syscall			! post_syscall(rvals)
551	nop
552	jmp	%l0 + 8				! return to user_rtt
553	nop
554	SET_SIZE(syscall_trap32)
555
556#endif /* lint */
557
558
559/*
560 * lwp_rtt - start execution in newly created LWP.
561 *	Here with t_post_sys set by lwp_create, and lwp_eosys == JUSTRETURN,
562 *	so that post_syscall() will run and the registers will
563 *	simply be restored.
564 *	This must go out through sys_rtt instead of syscall_rtt.
565 */
566#if defined(lint) || defined(__lint)
567
568void
569lwp_rtt_initial(void)
570{}
571
572void
573lwp_rtt(void)
574{}
575
576#else	/* lint */
577	ENTRY_NP(lwp_rtt_initial)
578	ldn	[THREAD_REG + T_STACK], %l7
579	call	__dtrace_probe___proc_start
580	sub	%l7, STACK_BIAS, %sp
581	ba	0f
582
583	ENTRY_NP(lwp_rtt)
584	ldn	[THREAD_REG + T_STACK], %l7
585	sub	%l7, STACK_BIAS, %sp
5860:
587	call	__dtrace_probe___proc_lwp__start
588	nop
589	call	dtrace_systrace_rtt
590	add	%sp, REGOFF + STACK_BIAS, %l7
591	ldx	[%l7 + O0_OFF], %o0
592	call	post_syscall
593	ldx	[%l7 + O1_OFF], %o1
594	ba,a,pt	%xcc, user_rtt
595	SET_SIZE(lwp_rtt)
596
597#endif	/* lint */
598