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
5*28406508Ssudheer * Common Development and Distribution License (the "License").
6*28406508Ssudheer * 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*28406508Ssudheer * 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#include <sys/asm_linkage.h>
277c478bd9Sstevel@tonic-gate#include <sys/privregs.h>
287c478bd9Sstevel@tonic-gate#include <sys/fsr.h>
297c478bd9Sstevel@tonic-gate#include <sys/asi.h>
30*28406508Ssudheer#include "assym.h"
317c478bd9Sstevel@tonic-gate
327c478bd9Sstevel@tonic-gate	ENTRY_NP(dtrace_getipl)
337c478bd9Sstevel@tonic-gate	retl
347c478bd9Sstevel@tonic-gate	rdpr	%pil, %o0
357c478bd9Sstevel@tonic-gate	SET_SIZE(dtrace_getipl)
367c478bd9Sstevel@tonic-gate
377c478bd9Sstevel@tonic-gate	ENTRY_NP(dtrace_getotherwin)
387c478bd9Sstevel@tonic-gate	retl
397c478bd9Sstevel@tonic-gate	rdpr	%otherwin, %o0
407c478bd9Sstevel@tonic-gate	SET_SIZE(dtrace_getotherwin)
417c478bd9Sstevel@tonic-gate
427c478bd9Sstevel@tonic-gate	ENTRY_NP(dtrace_getfprs)
437c478bd9Sstevel@tonic-gate	retl
447c478bd9Sstevel@tonic-gate	rd	%fprs, %o0
457c478bd9Sstevel@tonic-gate	SET_SIZE(dtrace_getfprs)
467c478bd9Sstevel@tonic-gate
477c478bd9Sstevel@tonic-gate	ENTRY_NP(dtrace_getfsr)
487c478bd9Sstevel@tonic-gate	rdpr	%pstate, %o1
497c478bd9Sstevel@tonic-gate	andcc	%o1, PSTATE_PEF, %g0
507c478bd9Sstevel@tonic-gate	bz,pn	%xcc, 1f
517c478bd9Sstevel@tonic-gate	nop
527c478bd9Sstevel@tonic-gate	rd	%fprs, %o1
537c478bd9Sstevel@tonic-gate	andcc	%o1, FPRS_FEF, %g0
547c478bd9Sstevel@tonic-gate	bz,pn	%xcc, 1f
557c478bd9Sstevel@tonic-gate	nop
567c478bd9Sstevel@tonic-gate	retl
577c478bd9Sstevel@tonic-gate	stx	%fsr, [%o0]
587c478bd9Sstevel@tonic-gate1:
597c478bd9Sstevel@tonic-gate	retl
607c478bd9Sstevel@tonic-gate	stx	%g0, [%o0]
617c478bd9Sstevel@tonic-gate	SET_SIZE(dtrace_getfsr)
627c478bd9Sstevel@tonic-gate
637c478bd9Sstevel@tonic-gate	ENTRY_NP(dtrace_getfp)
647c478bd9Sstevel@tonic-gate	retl
657c478bd9Sstevel@tonic-gate	mov	%fp, %o0
667c478bd9Sstevel@tonic-gate	SET_SIZE(dtrace_getfp)
677c478bd9Sstevel@tonic-gate
687c478bd9Sstevel@tonic-gate	ENTRY_NP(dtrace_flush_user_windows)
697c478bd9Sstevel@tonic-gate	rdpr	%otherwin, %g1
707c478bd9Sstevel@tonic-gate	brz	%g1, 3f
717c478bd9Sstevel@tonic-gate	clr	%g2
727c478bd9Sstevel@tonic-gate1:
737c478bd9Sstevel@tonic-gate	save	%sp, -WINDOWSIZE, %sp
747c478bd9Sstevel@tonic-gate	rdpr	%otherwin, %g1
757c478bd9Sstevel@tonic-gate	brnz	%g1, 1b
767c478bd9Sstevel@tonic-gate	add	%g2, 1, %g2
777c478bd9Sstevel@tonic-gate2:
787c478bd9Sstevel@tonic-gate	sub	%g2, 1, %g2		! restore back to orig window
797c478bd9Sstevel@tonic-gate	brnz	%g2, 2b
807c478bd9Sstevel@tonic-gate	restore
817c478bd9Sstevel@tonic-gate3:
827c478bd9Sstevel@tonic-gate	retl
837c478bd9Sstevel@tonic-gate	nop
847c478bd9Sstevel@tonic-gate	SET_SIZE(dtrace_flush_user_windows)
857c478bd9Sstevel@tonic-gate
867c478bd9Sstevel@tonic-gate	ENTRY(dtrace_cas32)
877c478bd9Sstevel@tonic-gate	cas	[%o0], %o1, %o2
887c478bd9Sstevel@tonic-gate	retl
897c478bd9Sstevel@tonic-gate	mov	%o2, %o0
907c478bd9Sstevel@tonic-gate	SET_SIZE(dtrace_cas32)
917c478bd9Sstevel@tonic-gate
927c478bd9Sstevel@tonic-gate	ENTRY(dtrace_casptr)
937c478bd9Sstevel@tonic-gate	casn	[%o0], %o1, %o2
947c478bd9Sstevel@tonic-gate	retl
957c478bd9Sstevel@tonic-gate	mov	%o2, %o0
967c478bd9Sstevel@tonic-gate	SET_SIZE(dtrace_casptr)
977c478bd9Sstevel@tonic-gate
987c478bd9Sstevel@tonic-gate	ENTRY(dtrace_caller)
997c478bd9Sstevel@tonic-gate	sethi	%hi(nwin_minus_one), %g4
1007c478bd9Sstevel@tonic-gate	ld	[%g4 + %lo(nwin_minus_one)], %g4
1017c478bd9Sstevel@tonic-gate	rdpr	%canrestore, %g2
1027c478bd9Sstevel@tonic-gate	cmp	%g2, %o0
1037c478bd9Sstevel@tonic-gate	bl	%icc, 1f
1047c478bd9Sstevel@tonic-gate	rdpr	%cwp, %g1
1057c478bd9Sstevel@tonic-gate	sub	%g1, %o0, %g3
1067c478bd9Sstevel@tonic-gate	brgez,a,pt %g3, 0f
1077c478bd9Sstevel@tonic-gate	wrpr	%g3, %cwp
1087c478bd9Sstevel@tonic-gate
1097c478bd9Sstevel@tonic-gate	!
1107c478bd9Sstevel@tonic-gate	! CWP minus the number of frames is negative; we must perform the
1117c478bd9Sstevel@tonic-gate	! arithmetic modulo MAXWIN.
1127c478bd9Sstevel@tonic-gate	!
1137c478bd9Sstevel@tonic-gate	add	%g4, %g3, %g3
1147c478bd9Sstevel@tonic-gate	inc	%g3
1157c478bd9Sstevel@tonic-gate	wrpr	%g3, %cwp
1167c478bd9Sstevel@tonic-gate0:
1177c478bd9Sstevel@tonic-gate	mov	%i7, %g4
1187c478bd9Sstevel@tonic-gate	wrpr	%g1, %cwp
1197c478bd9Sstevel@tonic-gate	retl
1207c478bd9Sstevel@tonic-gate	mov	%g4, %o0
1217c478bd9Sstevel@tonic-gate1:
1227c478bd9Sstevel@tonic-gate	!
1237c478bd9Sstevel@tonic-gate	! The caller has been flushed to the stack.  This is unlikely
1247c478bd9Sstevel@tonic-gate	! (interrupts are disabled in dtrace_probe()), but possible (the
1257c478bd9Sstevel@tonic-gate	! interrupt inducing the spill may have been taken before the
1267c478bd9Sstevel@tonic-gate	! call to dtrace_probe()).
1277c478bd9Sstevel@tonic-gate	!
1287c478bd9Sstevel@tonic-gate	retl
1297c478bd9Sstevel@tonic-gate	mov	-1, %o0
1307c478bd9Sstevel@tonic-gate	SET_SIZE(dtrace_caller)
1317c478bd9Sstevel@tonic-gate
1327c478bd9Sstevel@tonic-gate	ENTRY(dtrace_fish)
1337c478bd9Sstevel@tonic-gate
1347c478bd9Sstevel@tonic-gate	rd	%pc, %g5
1357c478bd9Sstevel@tonic-gate	ba	0f
1367c478bd9Sstevel@tonic-gate	add	%g5, 12, %g5
1377c478bd9Sstevel@tonic-gate	mov	%l0, %g4
1387c478bd9Sstevel@tonic-gate	mov	%l1, %g4
1397c478bd9Sstevel@tonic-gate	mov	%l2, %g4
1407c478bd9Sstevel@tonic-gate	mov	%l3, %g4
1417c478bd9Sstevel@tonic-gate	mov	%l4, %g4
1427c478bd9Sstevel@tonic-gate	mov	%l5, %g4
1437c478bd9Sstevel@tonic-gate	mov	%l6, %g4
1447c478bd9Sstevel@tonic-gate	mov	%l7, %g4
1457c478bd9Sstevel@tonic-gate	mov	%i0, %g4
1467c478bd9Sstevel@tonic-gate	mov	%i1, %g4
1477c478bd9Sstevel@tonic-gate	mov	%i2, %g4
1487c478bd9Sstevel@tonic-gate	mov	%i3, %g4
1497c478bd9Sstevel@tonic-gate	mov	%i4, %g4
1507c478bd9Sstevel@tonic-gate	mov	%i5, %g4
1517c478bd9Sstevel@tonic-gate	mov	%i6, %g4
1527c478bd9Sstevel@tonic-gate	mov	%i7, %g4
1537c478bd9Sstevel@tonic-gate0:
1547c478bd9Sstevel@tonic-gate	sub	%o1, 16, %o1		! Can only retrieve %l's and %i's
1557c478bd9Sstevel@tonic-gate	sll	%o1, 2, %o1		! Multiply by instruction size
1567c478bd9Sstevel@tonic-gate	add	%g5, %o1, %g5		! %g5 now contains the instr. to pick
1577c478bd9Sstevel@tonic-gate
1587c478bd9Sstevel@tonic-gate	sethi	%hi(nwin_minus_one), %g4
1597c478bd9Sstevel@tonic-gate	ld	[%g4 + %lo(nwin_minus_one)], %g4
1607c478bd9Sstevel@tonic-gate
1617c478bd9Sstevel@tonic-gate	!
1627c478bd9Sstevel@tonic-gate	! First we need to see if the frame that we're fishing in is still
1637c478bd9Sstevel@tonic-gate	! contained in the register windows.
1647c478bd9Sstevel@tonic-gate	!
1657c478bd9Sstevel@tonic-gate	rdpr	%canrestore, %g2
1667c478bd9Sstevel@tonic-gate	cmp	%g2, %o0
1677c478bd9Sstevel@tonic-gate	bl	%icc, 2f
1687c478bd9Sstevel@tonic-gate	rdpr	%cwp, %g1
1697c478bd9Sstevel@tonic-gate	sub	%g1, %o0, %g3
1707c478bd9Sstevel@tonic-gate	brgez,a,pt %g3, 0f
1717c478bd9Sstevel@tonic-gate	wrpr	%g3, %cwp
1727c478bd9Sstevel@tonic-gate
1737c478bd9Sstevel@tonic-gate	!
1747c478bd9Sstevel@tonic-gate	! CWP minus the number of frames is negative; we must perform the
1757c478bd9Sstevel@tonic-gate	! arithmetic modulo MAXWIN.
1767c478bd9Sstevel@tonic-gate	!
1777c478bd9Sstevel@tonic-gate	add	%g4, %g3, %g3
1787c478bd9Sstevel@tonic-gate	inc	%g3
1797c478bd9Sstevel@tonic-gate	wrpr	%g3, %cwp
1807c478bd9Sstevel@tonic-gate0:
1817c478bd9Sstevel@tonic-gate	jmp	%g5
1827c478bd9Sstevel@tonic-gate	ba	1f
1837c478bd9Sstevel@tonic-gate1:
1847c478bd9Sstevel@tonic-gate	wrpr	%g1, %cwp
1857c478bd9Sstevel@tonic-gate	stn	%g4, [%o2]
1867c478bd9Sstevel@tonic-gate	retl
1877c478bd9Sstevel@tonic-gate	clr	%o0			! Success; return 0.
1887c478bd9Sstevel@tonic-gate2:
1897c478bd9Sstevel@tonic-gate	!
1907c478bd9Sstevel@tonic-gate	! The frame that we're looking for has been flushed to the stack; the
1917c478bd9Sstevel@tonic-gate	! caller will be forced to
1927c478bd9Sstevel@tonic-gate	!
1937c478bd9Sstevel@tonic-gate	retl
1947c478bd9Sstevel@tonic-gate	add	%g2, 1, %o0		! Failure; return deepest frame + 1
1957c478bd9Sstevel@tonic-gate	SET_SIZE(dtrace_fish)
1967c478bd9Sstevel@tonic-gate
1977c478bd9Sstevel@tonic-gate	ENTRY(dtrace_copyin)
1987c478bd9Sstevel@tonic-gate	tst	%o2
199*28406508Ssudheer	bz	2f
2007c478bd9Sstevel@tonic-gate	clr	%g1
2017c478bd9Sstevel@tonic-gate	lduba	[%o0 + %g1]ASI_USER, %g2
2027c478bd9Sstevel@tonic-gate0:
203*28406508Ssudheer	! check for an error if the count is 4k-aligned
204*28406508Ssudheer	andcc	%g1, 0xfff, %g0
205*28406508Ssudheer	bnz,pt	%icc, 1f
2067c478bd9Sstevel@tonic-gate	stub	%g2, [%o1 + %g1]
207*28406508Ssudheer	lduh	[%o3], %g3
208*28406508Ssudheer	andcc	%g3, CPU_DTRACE_BADADDR, %g0
209*28406508Ssudheer	bnz,pn	%icc, 2f
210*28406508Ssudheer	nop
211*28406508Ssudheer1:
2127c478bd9Sstevel@tonic-gate	inc	%g1
2137c478bd9Sstevel@tonic-gate	cmp	%g1, %o2
2147c478bd9Sstevel@tonic-gate	bl,a	0b
2157c478bd9Sstevel@tonic-gate	lduba	[%o0 + %g1]ASI_USER, %g2
216*28406508Ssudheer2:
2177c478bd9Sstevel@tonic-gate	retl
2187c478bd9Sstevel@tonic-gate	nop
2197c478bd9Sstevel@tonic-gate
2207c478bd9Sstevel@tonic-gate	SET_SIZE(dtrace_copyin)
2217c478bd9Sstevel@tonic-gate
2227c478bd9Sstevel@tonic-gate	ENTRY(dtrace_copyinstr)
2237c478bd9Sstevel@tonic-gate	tst	%o2
224*28406508Ssudheer	bz	2f
2257c478bd9Sstevel@tonic-gate	clr	%g1
2267c478bd9Sstevel@tonic-gate	lduba	[%o0 + %g1]ASI_USER, %g2
2277c478bd9Sstevel@tonic-gate0:
2287c478bd9Sstevel@tonic-gate	stub	%g2, [%o1 + %g1]		! Store byte
229*28406508Ssudheer
230*28406508Ssudheer	! check for an error if the count is 4k-aligned
231*28406508Ssudheer	andcc	%g1, 0xfff, %g0
232*28406508Ssudheer	bnz,pt	%icc, 1f
233*28406508Ssudheer	inc	%g1
234*28406508Ssudheer	lduh	[%o3], %g3
235*28406508Ssudheer	andcc	%g3, CPU_DTRACE_BADADDR, %g0
236*28406508Ssudheer	bnz,pn	%icc, 2f
237*28406508Ssudheer	nop
238*28406508Ssudheer1:
2397c478bd9Sstevel@tonic-gate	cmp	%g2, 0				! Was that '\0'?
240*28406508Ssudheer	be	2f				! If so, we're done
2417c478bd9Sstevel@tonic-gate	cmp	%g1, %o2			! Compare to limit
2427c478bd9Sstevel@tonic-gate	bl,a	0b				! If less, take another lap
2437c478bd9Sstevel@tonic-gate	lduba	[%o0 + %g1]ASI_USER, %g2	!   delay: load user byte
244*28406508Ssudheer2:
2457c478bd9Sstevel@tonic-gate	retl
2467c478bd9Sstevel@tonic-gate	nop
2477c478bd9Sstevel@tonic-gate
2487c478bd9Sstevel@tonic-gate	SET_SIZE(dtrace_copyinstr)
2497c478bd9Sstevel@tonic-gate
2507c478bd9Sstevel@tonic-gate	ENTRY(dtrace_copyout)
2517c478bd9Sstevel@tonic-gate	tst	%o2
252*28406508Ssudheer	bz	2f
2537c478bd9Sstevel@tonic-gate	clr	%g1
2547c478bd9Sstevel@tonic-gate	ldub	[%o0 + %g1], %g2
2557c478bd9Sstevel@tonic-gate0:
256*28406508Ssudheer	! check for an error if the count is 4k-aligned
257*28406508Ssudheer	andcc	%g1, 0xfff, %g0
258*28406508Ssudheer	bnz,pt	%icc, 1f
2597c478bd9Sstevel@tonic-gate	stba	%g2, [%o1 + %g1]ASI_USER
260*28406508Ssudheer	lduh	[%o3], %g3
261*28406508Ssudheer	andcc	%g3, CPU_DTRACE_BADADDR, %g0
262*28406508Ssudheer	bnz,pn	%icc, 2f
263*28406508Ssudheer	nop
264*28406508Ssudheer1:
2657c478bd9Sstevel@tonic-gate	inc	%g1
2667c478bd9Sstevel@tonic-gate	cmp	%g1, %o2
2677c478bd9Sstevel@tonic-gate	bl,a	0b
2687c478bd9Sstevel@tonic-gate	ldub	[%o0 + %g1], %g2
269*28406508Ssudheer2:
2707c478bd9Sstevel@tonic-gate	retl
2717c478bd9Sstevel@tonic-gate	nop
2727c478bd9Sstevel@tonic-gate	SET_SIZE(dtrace_copyout)
2737c478bd9Sstevel@tonic-gate
2747c478bd9Sstevel@tonic-gate	ENTRY(dtrace_copyoutstr)
2757c478bd9Sstevel@tonic-gate	tst	%o2
276*28406508Ssudheer	bz	2f
2777c478bd9Sstevel@tonic-gate	clr	%g1
2787c478bd9Sstevel@tonic-gate	ldub	[%o0 + %g1], %g2
2797c478bd9Sstevel@tonic-gate0:
2807c478bd9Sstevel@tonic-gate	stba	%g2, [%o1 + %g1]ASI_USER
281*28406508Ssudheer
282*28406508Ssudheer	! check for an error if the count is 4k-aligned
283*28406508Ssudheer	andcc	%g1, 0xfff, %g0
284*28406508Ssudheer	bnz,pt  %icc, 1f
2857c478bd9Sstevel@tonic-gate	inc	%g1
286*28406508Ssudheer	lduh	[%o3], %g3
287*28406508Ssudheer	andcc	%g3, CPU_DTRACE_BADADDR, %g0
288*28406508Ssudheer	bnz,pn	%icc, 2f
289*28406508Ssudheer	nop
290*28406508Ssudheer1:
291*28406508Ssudheer	cmp	%g2, 0
292*28406508Ssudheer	be	2f
2937c478bd9Sstevel@tonic-gate	cmp	%g1, %o2
2947c478bd9Sstevel@tonic-gate	bl,a	0b
2957c478bd9Sstevel@tonic-gate	ldub	[%o0 + %g1], %g2
296*28406508Ssudheer2:
2977c478bd9Sstevel@tonic-gate	retl
2987c478bd9Sstevel@tonic-gate	nop
2997c478bd9Sstevel@tonic-gate	SET_SIZE(dtrace_copyoutstr)
3007c478bd9Sstevel@tonic-gate
3017c478bd9Sstevel@tonic-gate	ENTRY(dtrace_fulword)
3027c478bd9Sstevel@tonic-gate	clr	%o1
3037c478bd9Sstevel@tonic-gate	ldna	[%o0]ASI_USER, %o1
3047c478bd9Sstevel@tonic-gate	retl
3057c478bd9Sstevel@tonic-gate	mov	%o1, %o0
3067c478bd9Sstevel@tonic-gate	SET_SIZE(dtrace_fulword)
3077c478bd9Sstevel@tonic-gate
3087c478bd9Sstevel@tonic-gate	ENTRY(dtrace_fuword8)
3097c478bd9Sstevel@tonic-gate	clr	%o1
3107c478bd9Sstevel@tonic-gate	lduba	[%o0]ASI_USER, %o1
3117c478bd9Sstevel@tonic-gate	retl
3127c478bd9Sstevel@tonic-gate	mov	%o1, %o0
3137c478bd9Sstevel@tonic-gate	SET_SIZE(dtrace_fuword8)
3147c478bd9Sstevel@tonic-gate
3157c478bd9Sstevel@tonic-gate	ENTRY(dtrace_fuword16)
3167c478bd9Sstevel@tonic-gate	clr	%o1
3177c478bd9Sstevel@tonic-gate	lduha	[%o0]ASI_USER, %o1
3187c478bd9Sstevel@tonic-gate	retl
3197c478bd9Sstevel@tonic-gate	mov	%o1, %o0
3207c478bd9Sstevel@tonic-gate	SET_SIZE(dtrace_fuword16)
3217c478bd9Sstevel@tonic-gate
3227c478bd9Sstevel@tonic-gate	ENTRY(dtrace_fuword32)
3237c478bd9Sstevel@tonic-gate	clr	%o1
3247c478bd9Sstevel@tonic-gate	lda	[%o0]ASI_USER, %o1
3257c478bd9Sstevel@tonic-gate	retl
3267c478bd9Sstevel@tonic-gate	mov	%o1, %o0
3277c478bd9Sstevel@tonic-gate	SET_SIZE(dtrace_fuword32)
3287c478bd9Sstevel@tonic-gate
3297c478bd9Sstevel@tonic-gate	ENTRY(dtrace_fuword64)
3307c478bd9Sstevel@tonic-gate	clr	%o1
3317c478bd9Sstevel@tonic-gate	ldxa	[%o0]ASI_USER, %o1
3327c478bd9Sstevel@tonic-gate	retl
3337c478bd9Sstevel@tonic-gate	mov	%o1, %o0
3347c478bd9Sstevel@tonic-gate	SET_SIZE(dtrace_fuword64)
3357c478bd9Sstevel@tonic-gate
3367c478bd9Sstevel@tonic-gate	/*
3377c478bd9Sstevel@tonic-gate	 * %g1	pcstack
3387c478bd9Sstevel@tonic-gate	 * %g2	current window
3397c478bd9Sstevel@tonic-gate	 * %g3	maxwin (nwindows - 1)
3407c478bd9Sstevel@tonic-gate	 * %g4	saved %cwp (so we can get back to the original window)
3417c478bd9Sstevel@tonic-gate	 * %g5	iteration count
3427c478bd9Sstevel@tonic-gate	 * %g6	saved %fp
3437c478bd9Sstevel@tonic-gate	 *
3447c478bd9Sstevel@tonic-gate	 * %o0	pcstack / return value (iteration count)
3457c478bd9Sstevel@tonic-gate	 * %o1	pcstack_limit
3467c478bd9Sstevel@tonic-gate	 * %o2	last_fp
3477c478bd9Sstevel@tonic-gate	 */
3487c478bd9Sstevel@tonic-gate
3497c478bd9Sstevel@tonic-gate	ENTRY(dtrace_getupcstack_top)
3507c478bd9Sstevel@tonic-gate	mov	%o0, %g1		! we need the pcstack pointer while
3517c478bd9Sstevel@tonic-gate					! we're visiting other windows
3527c478bd9Sstevel@tonic-gate
3537c478bd9Sstevel@tonic-gate	rdpr	%otherwin, %g5		! compute the number of iterations
3547c478bd9Sstevel@tonic-gate	cmp	%g5, %o1		! (windows to observe) by taking the
3557c478bd9Sstevel@tonic-gate	movg	%icc, %o1, %g5		! min of %otherwin and pcstack_limit
3567c478bd9Sstevel@tonic-gate
3577c478bd9Sstevel@tonic-gate	brlez,a,pn %g5, 2f		! return 0 if count <= 0
3587c478bd9Sstevel@tonic-gate	clr	%o0
3597c478bd9Sstevel@tonic-gate
3607c478bd9Sstevel@tonic-gate	sethi	%hi(nwin_minus_one), %g3 ! hang onto maxwin since we'll need
3617c478bd9Sstevel@tonic-gate	ld	[%g3 + %lo(nwin_minus_one)], %g3 ! it for our modular arithmetic
3627c478bd9Sstevel@tonic-gate
3637c478bd9Sstevel@tonic-gate	rdpr	%cwp, %g4		! remember our window so we can return
3647c478bd9Sstevel@tonic-gate	rdpr	%canrestore, %g2	! compute the first non-user window
3650b38a8bdSahl	subcc	%g4, %g2, %g2		! current = %cwp - %canrestore
3667c478bd9Sstevel@tonic-gate
3677c478bd9Sstevel@tonic-gate	bge,pt	%xcc, 1f		! good to go if current is >= 0
3687c478bd9Sstevel@tonic-gate	mov	%g5, %o0		! we need to return the count
3697c478bd9Sstevel@tonic-gate
3707c478bd9Sstevel@tonic-gate	add	%g2, %g3, %g2		! normalize our current window if it's
3717c478bd9Sstevel@tonic-gate	add	%g2, 1, %g2		! less than zero
3727c478bd9Sstevel@tonic-gate
3737c478bd9Sstevel@tonic-gate	! note that while it's tempting, we can't execute restore to decrement
3747c478bd9Sstevel@tonic-gate	! the %cwp by one (mod nwindows) because we're in the user's windows
3757c478bd9Sstevel@tonic-gate1:
3767c478bd9Sstevel@tonic-gate	deccc	%g2			! decrement the current window
3777c478bd9Sstevel@tonic-gate	movl	%xcc, %g3, %g2		! normalize if it's negative (-1)
3787c478bd9Sstevel@tonic-gate
3797c478bd9Sstevel@tonic-gate	wrpr	%g2, %cwp		! change windows
3807c478bd9Sstevel@tonic-gate
3817c478bd9Sstevel@tonic-gate	stx	%i7, [%g1]		! stash the return address in pcstack
3827c478bd9Sstevel@tonic-gate
3837c478bd9Sstevel@tonic-gate	deccc	%g5			! decrement the count
3847c478bd9Sstevel@tonic-gate	bnz,pt	%icc, 1b		! we iterate until the count reaches 0
3857c478bd9Sstevel@tonic-gate	add	%g1, 8, %g1		! increment the pcstack pointer
3867c478bd9Sstevel@tonic-gate
3877c478bd9Sstevel@tonic-gate	mov	%i6, %g6		! stash the last frame pointer we
3887c478bd9Sstevel@tonic-gate					! encounter so the caller can
3897c478bd9Sstevel@tonic-gate					! continue the stack walk in memory
3907c478bd9Sstevel@tonic-gate
3917c478bd9Sstevel@tonic-gate	wrpr	%g4, %cwp		! change back to the original window
3927c478bd9Sstevel@tonic-gate
3937c478bd9Sstevel@tonic-gate	stn	%g6, [%o2]		! return the last frame pointer
3947c478bd9Sstevel@tonic-gate
3957c478bd9Sstevel@tonic-gate2:
3967c478bd9Sstevel@tonic-gate	retl
3977c478bd9Sstevel@tonic-gate	nop
3987c478bd9Sstevel@tonic-gate	SET_SIZE(dtrace_getupcstack_top)
3997c478bd9Sstevel@tonic-gate
4000b38a8bdSahl	ENTRY(dtrace_getustackdepth_top)
4010b38a8bdSahl	mov	%o0, %o2
4020b38a8bdSahl	rdpr	%otherwin, %o0
4030b38a8bdSahl
4040b38a8bdSahl	brlez,a,pn %o0, 2f		! return 0 if there are no user wins
4050b38a8bdSahl	clr	%o0
4060b38a8bdSahl
4070b38a8bdSahl	rdpr	%cwp, %g4		! remember our window so we can return
4080b38a8bdSahl	rdpr	%canrestore, %g2	! compute the first user window
4090b38a8bdSahl	sub	%g4, %g2, %g2		! current = %cwp - %canrestore -
4100b38a8bdSahl	subcc	%g2, %o0, %g2		!     %otherwin
4110b38a8bdSahl
4120b38a8bdSahl	bge,pt	%xcc, 1f		! normalize the window if necessary
4130b38a8bdSahl	sethi	%hi(nwin_minus_one), %g3
4140b38a8bdSahl	ld	[%g3 + %lo(nwin_minus_one)], %g3
4150b38a8bdSahl	add	%g2, %g3, %g2
4160b38a8bdSahl	add	%g2, 1, %g2
4170b38a8bdSahl
4180b38a8bdSahl1:
4190b38a8bdSahl	wrpr	%g2, %cwp		! change to the first user window
4200b38a8bdSahl	mov	%i6, %g6		! stash the frame pointer
4210b38a8bdSahl	wrpr	%g4, %cwp		! change back to the original window
4220b38a8bdSahl
4230b38a8bdSahl	stn	%g6, [%o2]		! return the frame pointer
4240b38a8bdSahl
4250b38a8bdSahl2:
4260b38a8bdSahl	retl
4270b38a8bdSahl	nop
4280b38a8bdSahl	SET_SIZE(dtrace_getustackdepth_top)
4290b38a8bdSahl
4307c478bd9Sstevel@tonic-gate	ENTRY(dtrace_getreg_win)
4317c478bd9Sstevel@tonic-gate	sub	%o0, 16, %o0
4327c478bd9Sstevel@tonic-gate	cmp	%o0, 16			! %o0 must begin in the range [16..32)
4337c478bd9Sstevel@tonic-gate	blu,pt	%xcc, 1f
4347c478bd9Sstevel@tonic-gate	nop
4357c478bd9Sstevel@tonic-gate	retl
4367c478bd9Sstevel@tonic-gate	clr	%o0
4377c478bd9Sstevel@tonic-gate
4387c478bd9Sstevel@tonic-gate1:
4397c478bd9Sstevel@tonic-gate	set	dtrace_getreg_win_table, %g3
4407c478bd9Sstevel@tonic-gate	sll	%o0, 2, %o0
4417c478bd9Sstevel@tonic-gate	add	%g3, %o0, %g3
4427c478bd9Sstevel@tonic-gate
4437c478bd9Sstevel@tonic-gate	rdpr	%canrestore, %o3
4447c478bd9Sstevel@tonic-gate	rdpr	%cwp, %g2
4457c478bd9Sstevel@tonic-gate
4467c478bd9Sstevel@tonic-gate	! Set %cwp to be (%cwp - %canrestore - %o1) mod NWINDOWS
4477c478bd9Sstevel@tonic-gate
4487c478bd9Sstevel@tonic-gate	sub	%g2, %o3, %o2		! %o2 is %cwp - %canrestore
4497c478bd9Sstevel@tonic-gate	subcc	%o2, %o1, %o4
4507c478bd9Sstevel@tonic-gate	bge,a,pn %xcc, 2f
4517c478bd9Sstevel@tonic-gate	wrpr	%o4, %cwp
4527c478bd9Sstevel@tonic-gate
4537c478bd9Sstevel@tonic-gate	sethi	%hi(nwin_minus_one), %o3
4547c478bd9Sstevel@tonic-gate	ld	[%o3 + %lo(nwin_minus_one)], %o3
4557c478bd9Sstevel@tonic-gate
4567c478bd9Sstevel@tonic-gate	add	%o2, %o3, %o4
4577c478bd9Sstevel@tonic-gate	wrpr	%o4, %cwp
4587c478bd9Sstevel@tonic-gate2:
4597c478bd9Sstevel@tonic-gate	jmp	%g3
4607c478bd9Sstevel@tonic-gate	ba	3f
4617c478bd9Sstevel@tonic-gate3:
4627c478bd9Sstevel@tonic-gate	wrpr	%g2, %cwp
4637c478bd9Sstevel@tonic-gate	retl
4647c478bd9Sstevel@tonic-gate	mov	%g1, %o0
4657c478bd9Sstevel@tonic-gate
4667c478bd9Sstevel@tonic-gatedtrace_getreg_win_table:
4677c478bd9Sstevel@tonic-gate	mov	%l0, %g1
4687c478bd9Sstevel@tonic-gate	mov	%l1, %g1
4697c478bd9Sstevel@tonic-gate	mov	%l2, %g1
4707c478bd9Sstevel@tonic-gate	mov	%l3, %g1
4717c478bd9Sstevel@tonic-gate	mov	%l4, %g1
4727c478bd9Sstevel@tonic-gate	mov	%l5, %g1
4737c478bd9Sstevel@tonic-gate	mov	%l6, %g1
4747c478bd9Sstevel@tonic-gate	mov	%l7, %g1
4757c478bd9Sstevel@tonic-gate	mov	%i0, %g1
4767c478bd9Sstevel@tonic-gate	mov	%i1, %g1
4777c478bd9Sstevel@tonic-gate	mov	%i2, %g1
4787c478bd9Sstevel@tonic-gate	mov	%i3, %g1
4797c478bd9Sstevel@tonic-gate	mov	%i4, %g1
4807c478bd9Sstevel@tonic-gate	mov	%i5, %g1
4817c478bd9Sstevel@tonic-gate	mov	%i6, %g1
4827c478bd9Sstevel@tonic-gate	mov	%i7, %g1
4837c478bd9Sstevel@tonic-gate	SET_SIZE(dtrace_getreg_win)
4847c478bd9Sstevel@tonic-gate
4857c478bd9Sstevel@tonic-gate	ENTRY(dtrace_putreg_win)
4867c478bd9Sstevel@tonic-gate	sub	%o0, 16, %o0
4877c478bd9Sstevel@tonic-gate	cmp	%o0, 16			! %o0 must be in the range [16..32)
4887c478bd9Sstevel@tonic-gate	blu,pt	%xcc, 1f
4897c478bd9Sstevel@tonic-gate	nop
4907c478bd9Sstevel@tonic-gate	retl
4917c478bd9Sstevel@tonic-gate	nop
4927c478bd9Sstevel@tonic-gate
4937c478bd9Sstevel@tonic-gate1:
4947c478bd9Sstevel@tonic-gate	mov	%o1, %g1		! move the value into a global register
4957c478bd9Sstevel@tonic-gate
4967c478bd9Sstevel@tonic-gate	set	dtrace_putreg_table, %g3
4977c478bd9Sstevel@tonic-gate	sll	%o0, 2, %o0
4987c478bd9Sstevel@tonic-gate	add	%g3, %o0, %g3
4997c478bd9Sstevel@tonic-gate
5007c478bd9Sstevel@tonic-gate	rdpr	%canrestore, %o3
5017c478bd9Sstevel@tonic-gate	rdpr	%cwp, %g2
5027c478bd9Sstevel@tonic-gate
5037c478bd9Sstevel@tonic-gate	! Set %cwp to be (%cwp - %canrestore - 1) mod NWINDOWS
5047c478bd9Sstevel@tonic-gate
5057c478bd9Sstevel@tonic-gate	sub	%g2, %o3, %o2		! %o2 is %cwp - %canrestore
5067c478bd9Sstevel@tonic-gate	subcc	%o2, 1, %o4
5077c478bd9Sstevel@tonic-gate	bge,a,pn %xcc, 2f
5087c478bd9Sstevel@tonic-gate	wrpr	%o4, %cwp
5097c478bd9Sstevel@tonic-gate
5107c478bd9Sstevel@tonic-gate	sethi	%hi(nwin_minus_one), %o3
5117c478bd9Sstevel@tonic-gate	ld	[%o3 + %lo(nwin_minus_one)], %o3
5127c478bd9Sstevel@tonic-gate	add	%o2, %o3, %o4
5137c478bd9Sstevel@tonic-gate	wrpr	%o4, %cwp
5147c478bd9Sstevel@tonic-gate2:
5157c478bd9Sstevel@tonic-gate	jmp	%g3
5167c478bd9Sstevel@tonic-gate	ba	3f
5177c478bd9Sstevel@tonic-gate3:
5187c478bd9Sstevel@tonic-gate	wrpr	%g2, %cwp
5197c478bd9Sstevel@tonic-gate	retl
5207c478bd9Sstevel@tonic-gate	nop
5217c478bd9Sstevel@tonic-gate
5227c478bd9Sstevel@tonic-gatedtrace_putreg_table:
5237c478bd9Sstevel@tonic-gate	mov	%g1, %l0
5247c478bd9Sstevel@tonic-gate	mov	%g1, %l1
5257c478bd9Sstevel@tonic-gate	mov	%g1, %l2
5267c478bd9Sstevel@tonic-gate	mov	%g1, %l3
5277c478bd9Sstevel@tonic-gate	mov	%g1, %l4
5287c478bd9Sstevel@tonic-gate	mov	%g1, %l5
5297c478bd9Sstevel@tonic-gate	mov	%g1, %l6
5307c478bd9Sstevel@tonic-gate	mov	%g1, %l7
5317c478bd9Sstevel@tonic-gate	mov	%g1, %i0
5327c478bd9Sstevel@tonic-gate	mov	%g1, %i1
5337c478bd9Sstevel@tonic-gate	mov	%g1, %i2
5347c478bd9Sstevel@tonic-gate	mov	%g1, %i3
5357c478bd9Sstevel@tonic-gate	mov	%g1, %i4
5367c478bd9Sstevel@tonic-gate	mov	%g1, %i5
5377c478bd9Sstevel@tonic-gate	mov	%g1, %i6
5387c478bd9Sstevel@tonic-gate	mov	%g1, %i7
5397c478bd9Sstevel@tonic-gate	SET_SIZE(dtrace_putreg_win)
5407c478bd9Sstevel@tonic-gate
5417c478bd9Sstevel@tonic-gate	ENTRY(dtrace_probe_error)
5427c478bd9Sstevel@tonic-gate	save	%sp, -SA(MINFRAME), %sp
5437c478bd9Sstevel@tonic-gate	sethi	%hi(dtrace_probeid_error), %l0
5447c478bd9Sstevel@tonic-gate	ld	[%l0 + %lo(dtrace_probeid_error)], %o0
5457c478bd9Sstevel@tonic-gate	mov	%i0, %o1
5467c478bd9Sstevel@tonic-gate	mov	%i1, %o2
5477c478bd9Sstevel@tonic-gate	mov	%i2, %o3
5487c478bd9Sstevel@tonic-gate	mov	%i3, %o4
5497c478bd9Sstevel@tonic-gate	call	dtrace_probe
5507c478bd9Sstevel@tonic-gate	mov	%i4, %o5
5517c478bd9Sstevel@tonic-gate	ret
5527c478bd9Sstevel@tonic-gate	restore
5537c478bd9Sstevel@tonic-gate	SET_SIZE(dtrace_probe_error)
5547c478bd9Sstevel@tonic-gate
555