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