10Sstevel@tonic-gate/* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*3677Ssudheer * Common Development and Distribution License (the "License"). 6*3677Ssudheer * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 210Sstevel@tonic-gate/* 22*3677Ssudheer * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 230Sstevel@tonic-gate * Use is subject to license terms. 240Sstevel@tonic-gate */ 250Sstevel@tonic-gate 260Sstevel@tonic-gate#pragma ident "%Z%%M% %I% %E% SMI" 270Sstevel@tonic-gate 280Sstevel@tonic-gate#if defined(lint) || defined(__lint) 290Sstevel@tonic-gate#include <sys/dtrace_impl.h> 300Sstevel@tonic-gate#else 310Sstevel@tonic-gate#include <sys/asm_linkage.h> 320Sstevel@tonic-gate#include <sys/privregs.h> 330Sstevel@tonic-gate#include <sys/fsr.h> 340Sstevel@tonic-gate#include <sys/asi.h> 35*3677Ssudheer#include "assym.h" 360Sstevel@tonic-gate#endif 370Sstevel@tonic-gate 380Sstevel@tonic-gate#if defined(lint) || defined(__lint) 390Sstevel@tonic-gate 400Sstevel@tonic-gateint 410Sstevel@tonic-gatedtrace_getipl(void) 420Sstevel@tonic-gate{ return (0); } 430Sstevel@tonic-gate 440Sstevel@tonic-gate#else /* lint */ 450Sstevel@tonic-gate 460Sstevel@tonic-gate ENTRY_NP(dtrace_getipl) 470Sstevel@tonic-gate retl 480Sstevel@tonic-gate rdpr %pil, %o0 490Sstevel@tonic-gate SET_SIZE(dtrace_getipl) 500Sstevel@tonic-gate 510Sstevel@tonic-gate#endif /* lint */ 520Sstevel@tonic-gate 530Sstevel@tonic-gate#if defined(lint) || defined(__lint) 540Sstevel@tonic-gate 550Sstevel@tonic-gateuint_t 560Sstevel@tonic-gatedtrace_getotherwin(void) 570Sstevel@tonic-gate{ return (0); } 580Sstevel@tonic-gate 590Sstevel@tonic-gate#else /* lint */ 600Sstevel@tonic-gate 610Sstevel@tonic-gate ENTRY_NP(dtrace_getotherwin) 620Sstevel@tonic-gate retl 630Sstevel@tonic-gate rdpr %otherwin, %o0 640Sstevel@tonic-gate SET_SIZE(dtrace_getotherwin) 650Sstevel@tonic-gate 660Sstevel@tonic-gate#endif /* lint */ 670Sstevel@tonic-gate 680Sstevel@tonic-gate#if defined(lint) || defined(__lint) 690Sstevel@tonic-gate 700Sstevel@tonic-gateuint_t 710Sstevel@tonic-gatedtrace_getfprs(void) 720Sstevel@tonic-gate{ return (0); } 730Sstevel@tonic-gate 740Sstevel@tonic-gate#else /* lint */ 750Sstevel@tonic-gate 760Sstevel@tonic-gate ENTRY_NP(dtrace_getfprs) 770Sstevel@tonic-gate retl 780Sstevel@tonic-gate rd %fprs, %o0 790Sstevel@tonic-gate SET_SIZE(dtrace_getfprs) 800Sstevel@tonic-gate 810Sstevel@tonic-gate#endif /* lint */ 820Sstevel@tonic-gate 830Sstevel@tonic-gate#if defined(lint) || defined(__lint) 840Sstevel@tonic-gate 850Sstevel@tonic-gate/*ARGSUSED*/ 860Sstevel@tonic-gatevoid 870Sstevel@tonic-gatedtrace_getfsr(uint64_t *val) 880Sstevel@tonic-gate{} 890Sstevel@tonic-gate 900Sstevel@tonic-gate#else /* lint */ 910Sstevel@tonic-gate 920Sstevel@tonic-gate ENTRY_NP(dtrace_getfsr) 930Sstevel@tonic-gate rdpr %pstate, %o1 940Sstevel@tonic-gate andcc %o1, PSTATE_PEF, %g0 950Sstevel@tonic-gate bz,pn %xcc, 1f 960Sstevel@tonic-gate nop 970Sstevel@tonic-gate rd %fprs, %o1 980Sstevel@tonic-gate andcc %o1, FPRS_FEF, %g0 990Sstevel@tonic-gate bz,pn %xcc, 1f 1000Sstevel@tonic-gate nop 1010Sstevel@tonic-gate retl 1020Sstevel@tonic-gate stx %fsr, [%o0] 1030Sstevel@tonic-gate1: 1040Sstevel@tonic-gate retl 1050Sstevel@tonic-gate stx %g0, [%o0] 1060Sstevel@tonic-gate SET_SIZE(dtrace_getfsr) 1070Sstevel@tonic-gate 1080Sstevel@tonic-gate#endif /* lint */ 1090Sstevel@tonic-gate 1100Sstevel@tonic-gate#if defined(lint) || defined(__lint) 1110Sstevel@tonic-gate 1120Sstevel@tonic-gategreg_t 1130Sstevel@tonic-gatedtrace_getfp(void) 1140Sstevel@tonic-gate{ return (0); } 1150Sstevel@tonic-gate 1160Sstevel@tonic-gate#else /* lint */ 1170Sstevel@tonic-gate 1180Sstevel@tonic-gate ENTRY_NP(dtrace_getfp) 1190Sstevel@tonic-gate retl 1200Sstevel@tonic-gate mov %fp, %o0 1210Sstevel@tonic-gate SET_SIZE(dtrace_getfp) 1220Sstevel@tonic-gate 1230Sstevel@tonic-gate#endif /* lint */ 1240Sstevel@tonic-gate 1250Sstevel@tonic-gate#if defined(lint) || defined(__lint) 1260Sstevel@tonic-gate 1270Sstevel@tonic-gatevoid 1280Sstevel@tonic-gatedtrace_flush_user_windows(void) 1290Sstevel@tonic-gate{} 1300Sstevel@tonic-gate 1310Sstevel@tonic-gate#else 1320Sstevel@tonic-gate 1330Sstevel@tonic-gate ENTRY_NP(dtrace_flush_user_windows) 1340Sstevel@tonic-gate rdpr %otherwin, %g1 1350Sstevel@tonic-gate brz %g1, 3f 1360Sstevel@tonic-gate clr %g2 1370Sstevel@tonic-gate1: 1380Sstevel@tonic-gate save %sp, -WINDOWSIZE, %sp 1390Sstevel@tonic-gate rdpr %otherwin, %g1 1400Sstevel@tonic-gate brnz %g1, 1b 1410Sstevel@tonic-gate add %g2, 1, %g2 1420Sstevel@tonic-gate2: 1430Sstevel@tonic-gate sub %g2, 1, %g2 ! restore back to orig window 1440Sstevel@tonic-gate brnz %g2, 2b 1450Sstevel@tonic-gate restore 1460Sstevel@tonic-gate3: 1470Sstevel@tonic-gate retl 1480Sstevel@tonic-gate nop 1490Sstevel@tonic-gate SET_SIZE(dtrace_flush_user_windows) 1500Sstevel@tonic-gate 1510Sstevel@tonic-gate#endif /* lint */ 1520Sstevel@tonic-gate 1530Sstevel@tonic-gate#if defined(lint) || defined(__lint) 1540Sstevel@tonic-gate 1550Sstevel@tonic-gateuint32_t 1560Sstevel@tonic-gatedtrace_cas32(uint32_t *target, uint32_t cmp, uint32_t new) 1570Sstevel@tonic-gate{ 1580Sstevel@tonic-gate uint32_t old; 1590Sstevel@tonic-gate 1600Sstevel@tonic-gate if ((old = *target) == cmp) 1610Sstevel@tonic-gate *target = new; 1620Sstevel@tonic-gate return (old); 1630Sstevel@tonic-gate} 1640Sstevel@tonic-gate 1650Sstevel@tonic-gatevoid * 1660Sstevel@tonic-gatedtrace_casptr(void *target, void *cmp, void *new) 1670Sstevel@tonic-gate{ 1680Sstevel@tonic-gate void *old; 1690Sstevel@tonic-gate 1700Sstevel@tonic-gate if ((old = *(void **)target) == cmp) 1710Sstevel@tonic-gate *(void **)target = new; 1720Sstevel@tonic-gate return (old); 1730Sstevel@tonic-gate} 1740Sstevel@tonic-gate 1750Sstevel@tonic-gate#else /* lint */ 1760Sstevel@tonic-gate 1770Sstevel@tonic-gate ENTRY(dtrace_cas32) 1780Sstevel@tonic-gate cas [%o0], %o1, %o2 1790Sstevel@tonic-gate retl 1800Sstevel@tonic-gate mov %o2, %o0 1810Sstevel@tonic-gate SET_SIZE(dtrace_cas32) 1820Sstevel@tonic-gate 1830Sstevel@tonic-gate ENTRY(dtrace_casptr) 1840Sstevel@tonic-gate casn [%o0], %o1, %o2 1850Sstevel@tonic-gate retl 1860Sstevel@tonic-gate mov %o2, %o0 1870Sstevel@tonic-gate SET_SIZE(dtrace_casptr) 1880Sstevel@tonic-gate 1890Sstevel@tonic-gate#endif /* lint */ 1900Sstevel@tonic-gate 1910Sstevel@tonic-gate#if defined(lint) 1920Sstevel@tonic-gate 1930Sstevel@tonic-gate/*ARGSUSED*/ 1940Sstevel@tonic-gateuintptr_t 1950Sstevel@tonic-gatedtrace_caller(int aframes) 1960Sstevel@tonic-gate{ 1970Sstevel@tonic-gate return (0); 1980Sstevel@tonic-gate} 1990Sstevel@tonic-gate 2000Sstevel@tonic-gate#else /* lint */ 2010Sstevel@tonic-gate 2020Sstevel@tonic-gate ENTRY(dtrace_caller) 2030Sstevel@tonic-gate sethi %hi(nwin_minus_one), %g4 2040Sstevel@tonic-gate ld [%g4 + %lo(nwin_minus_one)], %g4 2050Sstevel@tonic-gate rdpr %canrestore, %g2 2060Sstevel@tonic-gate cmp %g2, %o0 2070Sstevel@tonic-gate bl %icc, 1f 2080Sstevel@tonic-gate rdpr %cwp, %g1 2090Sstevel@tonic-gate sub %g1, %o0, %g3 2100Sstevel@tonic-gate brgez,a,pt %g3, 0f 2110Sstevel@tonic-gate wrpr %g3, %cwp 2120Sstevel@tonic-gate 2130Sstevel@tonic-gate ! 2140Sstevel@tonic-gate ! CWP minus the number of frames is negative; we must perform the 2150Sstevel@tonic-gate ! arithmetic modulo MAXWIN. 2160Sstevel@tonic-gate ! 2170Sstevel@tonic-gate add %g4, %g3, %g3 2180Sstevel@tonic-gate inc %g3 2190Sstevel@tonic-gate wrpr %g3, %cwp 2200Sstevel@tonic-gate0: 2210Sstevel@tonic-gate mov %i7, %g4 2220Sstevel@tonic-gate wrpr %g1, %cwp 2230Sstevel@tonic-gate retl 2240Sstevel@tonic-gate mov %g4, %o0 2250Sstevel@tonic-gate1: 2260Sstevel@tonic-gate ! 2270Sstevel@tonic-gate ! The caller has been flushed to the stack. This is unlikely 2280Sstevel@tonic-gate ! (interrupts are disabled in dtrace_probe()), but possible (the 2290Sstevel@tonic-gate ! interrupt inducing the spill may have been taken before the 2300Sstevel@tonic-gate ! call to dtrace_probe()). 2310Sstevel@tonic-gate ! 2320Sstevel@tonic-gate retl 2330Sstevel@tonic-gate mov -1, %o0 2340Sstevel@tonic-gate SET_SIZE(dtrace_caller) 2350Sstevel@tonic-gate 2360Sstevel@tonic-gate#endif 2370Sstevel@tonic-gate 2380Sstevel@tonic-gate#if defined(lint) 2390Sstevel@tonic-gate 2400Sstevel@tonic-gate/*ARGSUSED*/ 2410Sstevel@tonic-gateint 2420Sstevel@tonic-gatedtrace_fish(int aframes, int reg, uintptr_t *regval) 2430Sstevel@tonic-gate{ 2440Sstevel@tonic-gate return (0); 2450Sstevel@tonic-gate} 2460Sstevel@tonic-gate 2470Sstevel@tonic-gate#else /* lint */ 2480Sstevel@tonic-gate 2490Sstevel@tonic-gate ENTRY(dtrace_fish) 2500Sstevel@tonic-gate 2510Sstevel@tonic-gate rd %pc, %g5 2520Sstevel@tonic-gate ba 0f 2530Sstevel@tonic-gate add %g5, 12, %g5 2540Sstevel@tonic-gate mov %l0, %g4 2550Sstevel@tonic-gate mov %l1, %g4 2560Sstevel@tonic-gate mov %l2, %g4 2570Sstevel@tonic-gate mov %l3, %g4 2580Sstevel@tonic-gate mov %l4, %g4 2590Sstevel@tonic-gate mov %l5, %g4 2600Sstevel@tonic-gate mov %l6, %g4 2610Sstevel@tonic-gate mov %l7, %g4 2620Sstevel@tonic-gate mov %i0, %g4 2630Sstevel@tonic-gate mov %i1, %g4 2640Sstevel@tonic-gate mov %i2, %g4 2650Sstevel@tonic-gate mov %i3, %g4 2660Sstevel@tonic-gate mov %i4, %g4 2670Sstevel@tonic-gate mov %i5, %g4 2680Sstevel@tonic-gate mov %i6, %g4 2690Sstevel@tonic-gate mov %i7, %g4 2700Sstevel@tonic-gate0: 2710Sstevel@tonic-gate sub %o1, 16, %o1 ! Can only retrieve %l's and %i's 2720Sstevel@tonic-gate sll %o1, 2, %o1 ! Multiply by instruction size 2730Sstevel@tonic-gate add %g5, %o1, %g5 ! %g5 now contains the instr. to pick 2740Sstevel@tonic-gate 2750Sstevel@tonic-gate sethi %hi(nwin_minus_one), %g4 2760Sstevel@tonic-gate ld [%g4 + %lo(nwin_minus_one)], %g4 2770Sstevel@tonic-gate 2780Sstevel@tonic-gate ! 2790Sstevel@tonic-gate ! First we need to see if the frame that we're fishing in is still 2800Sstevel@tonic-gate ! contained in the register windows. 2810Sstevel@tonic-gate ! 2820Sstevel@tonic-gate rdpr %canrestore, %g2 2830Sstevel@tonic-gate cmp %g2, %o0 2840Sstevel@tonic-gate bl %icc, 2f 2850Sstevel@tonic-gate rdpr %cwp, %g1 2860Sstevel@tonic-gate sub %g1, %o0, %g3 2870Sstevel@tonic-gate brgez,a,pt %g3, 0f 2880Sstevel@tonic-gate wrpr %g3, %cwp 2890Sstevel@tonic-gate 2900Sstevel@tonic-gate ! 2910Sstevel@tonic-gate ! CWP minus the number of frames is negative; we must perform the 2920Sstevel@tonic-gate ! arithmetic modulo MAXWIN. 2930Sstevel@tonic-gate ! 2940Sstevel@tonic-gate add %g4, %g3, %g3 2950Sstevel@tonic-gate inc %g3 2960Sstevel@tonic-gate wrpr %g3, %cwp 2970Sstevel@tonic-gate0: 2980Sstevel@tonic-gate jmp %g5 2990Sstevel@tonic-gate ba 1f 3000Sstevel@tonic-gate1: 3010Sstevel@tonic-gate wrpr %g1, %cwp 3020Sstevel@tonic-gate stn %g4, [%o2] 3030Sstevel@tonic-gate retl 3040Sstevel@tonic-gate clr %o0 ! Success; return 0. 3050Sstevel@tonic-gate2: 3060Sstevel@tonic-gate ! 3070Sstevel@tonic-gate ! The frame that we're looking for has been flushed to the stack; the 3080Sstevel@tonic-gate ! caller will be forced to 3090Sstevel@tonic-gate ! 3100Sstevel@tonic-gate retl 3110Sstevel@tonic-gate add %g2, 1, %o0 ! Failure; return deepest frame + 1 3120Sstevel@tonic-gate SET_SIZE(dtrace_fish) 3130Sstevel@tonic-gate 3140Sstevel@tonic-gate#endif 3150Sstevel@tonic-gate 3160Sstevel@tonic-gate#if defined(lint) 3170Sstevel@tonic-gate 3180Sstevel@tonic-gate/*ARGSUSED*/ 3190Sstevel@tonic-gatevoid 320*3677Ssudheerdtrace_copyin(uintptr_t uaddr, uintptr_t kaddr, size_t size, 321*3677Ssudheer volatile uint16_t *flags) 3220Sstevel@tonic-gate{} 3230Sstevel@tonic-gate 3240Sstevel@tonic-gate#else 3250Sstevel@tonic-gate 3260Sstevel@tonic-gate ENTRY(dtrace_copyin) 3270Sstevel@tonic-gate tst %o2 328*3677Ssudheer bz 2f 3290Sstevel@tonic-gate clr %g1 3300Sstevel@tonic-gate lduba [%o0 + %g1]ASI_USER, %g2 3310Sstevel@tonic-gate0: 332*3677Ssudheer ! check for an error if the count is 4k-aligned 333*3677Ssudheer andcc %g1, 0xfff, %g0 334*3677Ssudheer bnz,pt %icc, 1f 3350Sstevel@tonic-gate stub %g2, [%o1 + %g1] 336*3677Ssudheer lduh [%o3], %g3 337*3677Ssudheer andcc %g3, CPU_DTRACE_BADADDR, %g0 338*3677Ssudheer bnz,pn %icc, 2f 339*3677Ssudheer nop 340*3677Ssudheer1: 3410Sstevel@tonic-gate inc %g1 3420Sstevel@tonic-gate cmp %g1, %o2 3430Sstevel@tonic-gate bl,a 0b 3440Sstevel@tonic-gate lduba [%o0 + %g1]ASI_USER, %g2 345*3677Ssudheer2: 3460Sstevel@tonic-gate retl 3470Sstevel@tonic-gate nop 3480Sstevel@tonic-gate 3490Sstevel@tonic-gate SET_SIZE(dtrace_copyin) 3500Sstevel@tonic-gate 3510Sstevel@tonic-gate#endif 3520Sstevel@tonic-gate 3530Sstevel@tonic-gate#if defined(lint) 3540Sstevel@tonic-gate 3550Sstevel@tonic-gate/*ARGSUSED*/ 3560Sstevel@tonic-gatevoid 357*3677Ssudheerdtrace_copyinstr(uintptr_t uaddr, uintptr_t kaddr, size_t size, 358*3677Ssudheer volatile uint16_t *flags) 3590Sstevel@tonic-gate{} 3600Sstevel@tonic-gate 3610Sstevel@tonic-gate#else 3620Sstevel@tonic-gate 3630Sstevel@tonic-gate ENTRY(dtrace_copyinstr) 3640Sstevel@tonic-gate tst %o2 365*3677Ssudheer bz 2f 3660Sstevel@tonic-gate clr %g1 3670Sstevel@tonic-gate lduba [%o0 + %g1]ASI_USER, %g2 3680Sstevel@tonic-gate0: 3690Sstevel@tonic-gate stub %g2, [%o1 + %g1] ! Store byte 370*3677Ssudheer 371*3677Ssudheer ! check for an error if the count is 4k-aligned 372*3677Ssudheer andcc %g1, 0xfff, %g0 373*3677Ssudheer bnz,pt %icc, 1f 374*3677Ssudheer inc %g1 375*3677Ssudheer lduh [%o3], %g3 376*3677Ssudheer andcc %g3, CPU_DTRACE_BADADDR, %g0 377*3677Ssudheer bnz,pn %icc, 2f 378*3677Ssudheer nop 379*3677Ssudheer1: 3800Sstevel@tonic-gate cmp %g2, 0 ! Was that '\0'? 381*3677Ssudheer be 2f ! If so, we're done 3820Sstevel@tonic-gate cmp %g1, %o2 ! Compare to limit 3830Sstevel@tonic-gate bl,a 0b ! If less, take another lap 3840Sstevel@tonic-gate lduba [%o0 + %g1]ASI_USER, %g2 ! delay: load user byte 385*3677Ssudheer2: 3860Sstevel@tonic-gate retl 3870Sstevel@tonic-gate nop 3880Sstevel@tonic-gate 3890Sstevel@tonic-gate SET_SIZE(dtrace_copyinstr) 3900Sstevel@tonic-gate 3910Sstevel@tonic-gate#endif 3920Sstevel@tonic-gate 3930Sstevel@tonic-gate#if defined(lint) 3940Sstevel@tonic-gate 3950Sstevel@tonic-gate/*ARGSUSED*/ 3960Sstevel@tonic-gatevoid 397*3677Ssudheerdtrace_copyout(uintptr_t kaddr, uintptr_t uaddr, size_t size, 398*3677Ssudheer volatile uint16_t *flags) 3990Sstevel@tonic-gate{} 4000Sstevel@tonic-gate 4010Sstevel@tonic-gate#else 4020Sstevel@tonic-gate 4030Sstevel@tonic-gate ENTRY(dtrace_copyout) 4040Sstevel@tonic-gate tst %o2 405*3677Ssudheer bz 2f 4060Sstevel@tonic-gate clr %g1 4070Sstevel@tonic-gate ldub [%o0 + %g1], %g2 4080Sstevel@tonic-gate0: 409*3677Ssudheer ! check for an error if the count is 4k-aligned 410*3677Ssudheer andcc %g1, 0xfff, %g0 411*3677Ssudheer bnz,pt %icc, 1f 4120Sstevel@tonic-gate stba %g2, [%o1 + %g1]ASI_USER 413*3677Ssudheer lduh [%o3], %g3 414*3677Ssudheer andcc %g3, CPU_DTRACE_BADADDR, %g0 415*3677Ssudheer bnz,pn %icc, 2f 416*3677Ssudheer nop 417*3677Ssudheer1: 4180Sstevel@tonic-gate inc %g1 4190Sstevel@tonic-gate cmp %g1, %o2 4200Sstevel@tonic-gate bl,a 0b 4210Sstevel@tonic-gate ldub [%o0 + %g1], %g2 422*3677Ssudheer2: 4230Sstevel@tonic-gate retl 4240Sstevel@tonic-gate nop 4250Sstevel@tonic-gate SET_SIZE(dtrace_copyout) 4260Sstevel@tonic-gate 4270Sstevel@tonic-gate#endif 4280Sstevel@tonic-gate 4290Sstevel@tonic-gate#if defined(lint) 4300Sstevel@tonic-gate 4310Sstevel@tonic-gate/*ARGSUSED*/ 4320Sstevel@tonic-gatevoid 433*3677Ssudheerdtrace_copyoutstr(uintptr_t kaddr, uintptr_t uaddr, size_t size, 434*3677Ssudheer volatile uint16_t *flags) 4350Sstevel@tonic-gate{} 4360Sstevel@tonic-gate 4370Sstevel@tonic-gate#else 4380Sstevel@tonic-gate 4390Sstevel@tonic-gate ENTRY(dtrace_copyoutstr) 4400Sstevel@tonic-gate tst %o2 441*3677Ssudheer bz 2f 4420Sstevel@tonic-gate clr %g1 4430Sstevel@tonic-gate ldub [%o0 + %g1], %g2 4440Sstevel@tonic-gate0: 4450Sstevel@tonic-gate stba %g2, [%o1 + %g1]ASI_USER 446*3677Ssudheer 447*3677Ssudheer ! check for an error if the count is 4k-aligned 448*3677Ssudheer andcc %g1, 0xfff, %g0 449*3677Ssudheer bnz,pt %icc, 1f 450*3677Ssudheer inc %g1 451*3677Ssudheer lduh [%o3], %g3 452*3677Ssudheer andcc %g3, CPU_DTRACE_BADADDR, %g0 453*3677Ssudheer bnz,pn %icc, 2f 454*3677Ssudheer nop 455*3677Ssudheer1: 4560Sstevel@tonic-gate cmp %g2, 0 457*3677Ssudheer be 2f 4580Sstevel@tonic-gate cmp %g1, %o2 4590Sstevel@tonic-gate bl,a 0b 4600Sstevel@tonic-gate ldub [%o0 + %g1], %g2 461*3677Ssudheer2: 4620Sstevel@tonic-gate retl 4630Sstevel@tonic-gate nop 4640Sstevel@tonic-gate SET_SIZE(dtrace_copyoutstr) 4650Sstevel@tonic-gate 4660Sstevel@tonic-gate#endif 4670Sstevel@tonic-gate 4680Sstevel@tonic-gate#if defined(lint) 4690Sstevel@tonic-gate 4700Sstevel@tonic-gate/*ARGSUSED*/ 4710Sstevel@tonic-gateuintptr_t 4720Sstevel@tonic-gatedtrace_fulword(void *addr) 4730Sstevel@tonic-gate{ return (0); } 4740Sstevel@tonic-gate 4750Sstevel@tonic-gate#else 4760Sstevel@tonic-gate 4770Sstevel@tonic-gate ENTRY(dtrace_fulword) 4780Sstevel@tonic-gate clr %o1 4790Sstevel@tonic-gate ldna [%o0]ASI_USER, %o1 4800Sstevel@tonic-gate retl 4810Sstevel@tonic-gate mov %o1, %o0 4820Sstevel@tonic-gate SET_SIZE(dtrace_fulword) 4830Sstevel@tonic-gate 4840Sstevel@tonic-gate#endif 4850Sstevel@tonic-gate 4860Sstevel@tonic-gate#if defined(lint) 4870Sstevel@tonic-gate 4880Sstevel@tonic-gate/*ARGSUSED*/ 4890Sstevel@tonic-gateuint8_t 4900Sstevel@tonic-gatedtrace_fuword8(void *addr) 4910Sstevel@tonic-gate{ return (0); } 4920Sstevel@tonic-gate 4930Sstevel@tonic-gate#else 4940Sstevel@tonic-gate 4950Sstevel@tonic-gate ENTRY(dtrace_fuword8) 4960Sstevel@tonic-gate clr %o1 4970Sstevel@tonic-gate lduba [%o0]ASI_USER, %o1 4980Sstevel@tonic-gate retl 4990Sstevel@tonic-gate mov %o1, %o0 5000Sstevel@tonic-gate SET_SIZE(dtrace_fuword8) 5010Sstevel@tonic-gate 5020Sstevel@tonic-gate#endif 5030Sstevel@tonic-gate 5040Sstevel@tonic-gate#if defined(lint) 5050Sstevel@tonic-gate 5060Sstevel@tonic-gate/*ARGSUSED*/ 5070Sstevel@tonic-gateuint16_t 5080Sstevel@tonic-gatedtrace_fuword16(void *addr) 5090Sstevel@tonic-gate{ return (0); } 5100Sstevel@tonic-gate 5110Sstevel@tonic-gate#else 5120Sstevel@tonic-gate 5130Sstevel@tonic-gate ENTRY(dtrace_fuword16) 5140Sstevel@tonic-gate clr %o1 5150Sstevel@tonic-gate lduha [%o0]ASI_USER, %o1 5160Sstevel@tonic-gate retl 5170Sstevel@tonic-gate mov %o1, %o0 5180Sstevel@tonic-gate SET_SIZE(dtrace_fuword16) 5190Sstevel@tonic-gate 5200Sstevel@tonic-gate#endif 5210Sstevel@tonic-gate 5220Sstevel@tonic-gate#if defined(lint) 5230Sstevel@tonic-gate 5240Sstevel@tonic-gate/*ARGSUSED*/ 5250Sstevel@tonic-gateuint32_t 5260Sstevel@tonic-gatedtrace_fuword32(void *addr) 5270Sstevel@tonic-gate{ return (0); } 5280Sstevel@tonic-gate 5290Sstevel@tonic-gate#else 5300Sstevel@tonic-gate 5310Sstevel@tonic-gate ENTRY(dtrace_fuword32) 5320Sstevel@tonic-gate clr %o1 5330Sstevel@tonic-gate lda [%o0]ASI_USER, %o1 5340Sstevel@tonic-gate retl 5350Sstevel@tonic-gate mov %o1, %o0 5360Sstevel@tonic-gate SET_SIZE(dtrace_fuword32) 5370Sstevel@tonic-gate 5380Sstevel@tonic-gate#endif 5390Sstevel@tonic-gate 5400Sstevel@tonic-gate#if defined(lint) 5410Sstevel@tonic-gate 5420Sstevel@tonic-gate/*ARGSUSED*/ 5430Sstevel@tonic-gateuint64_t 5440Sstevel@tonic-gatedtrace_fuword64(void *addr) 5450Sstevel@tonic-gate{ return (0); } 5460Sstevel@tonic-gate 5470Sstevel@tonic-gate#else 5480Sstevel@tonic-gate 5490Sstevel@tonic-gate ENTRY(dtrace_fuword64) 5500Sstevel@tonic-gate clr %o1 5510Sstevel@tonic-gate ldxa [%o0]ASI_USER, %o1 5520Sstevel@tonic-gate retl 5530Sstevel@tonic-gate mov %o1, %o0 5540Sstevel@tonic-gate SET_SIZE(dtrace_fuword64) 5550Sstevel@tonic-gate 5560Sstevel@tonic-gate#endif 5570Sstevel@tonic-gate 5580Sstevel@tonic-gate#if defined(lint) 5590Sstevel@tonic-gate 5600Sstevel@tonic-gate/*ARGSUSED*/ 5610Sstevel@tonic-gateint 5620Sstevel@tonic-gatedtrace_getupcstack_top(uint64_t *pcstack, int pcstack_limit, uintptr_t *sp) 5630Sstevel@tonic-gate{ return (0); } 5640Sstevel@tonic-gate 5650Sstevel@tonic-gate#else 5660Sstevel@tonic-gate 5670Sstevel@tonic-gate /* 5680Sstevel@tonic-gate * %g1 pcstack 5690Sstevel@tonic-gate * %g2 current window 5700Sstevel@tonic-gate * %g3 maxwin (nwindows - 1) 5710Sstevel@tonic-gate * %g4 saved %cwp (so we can get back to the original window) 5720Sstevel@tonic-gate * %g5 iteration count 5730Sstevel@tonic-gate * %g6 saved %fp 5740Sstevel@tonic-gate * 5750Sstevel@tonic-gate * %o0 pcstack / return value (iteration count) 5760Sstevel@tonic-gate * %o1 pcstack_limit 5770Sstevel@tonic-gate * %o2 last_fp 5780Sstevel@tonic-gate */ 5790Sstevel@tonic-gate 5800Sstevel@tonic-gate ENTRY(dtrace_getupcstack_top) 5810Sstevel@tonic-gate mov %o0, %g1 ! we need the pcstack pointer while 5820Sstevel@tonic-gate ! we're visiting other windows 5830Sstevel@tonic-gate 5840Sstevel@tonic-gate rdpr %otherwin, %g5 ! compute the number of iterations 5850Sstevel@tonic-gate cmp %g5, %o1 ! (windows to observe) by taking the 5860Sstevel@tonic-gate movg %icc, %o1, %g5 ! min of %otherwin and pcstack_limit 5870Sstevel@tonic-gate 5880Sstevel@tonic-gate brlez,a,pn %g5, 2f ! return 0 if count <= 0 5890Sstevel@tonic-gate clr %o0 5900Sstevel@tonic-gate 5910Sstevel@tonic-gate sethi %hi(nwin_minus_one), %g3 ! hang onto maxwin since we'll need 5920Sstevel@tonic-gate ld [%g3 + %lo(nwin_minus_one)], %g3 ! it for our modular arithmetic 5930Sstevel@tonic-gate 5940Sstevel@tonic-gate rdpr %cwp, %g4 ! remember our window so we can return 5950Sstevel@tonic-gate rdpr %canrestore, %g2 ! compute the first non-user window 596191Sahl subcc %g4, %g2, %g2 ! current = %cwp - %canrestore 5970Sstevel@tonic-gate 5980Sstevel@tonic-gate bge,pt %xcc, 1f ! good to go if current is >= 0 5990Sstevel@tonic-gate mov %g5, %o0 ! we need to return the count 6000Sstevel@tonic-gate 6010Sstevel@tonic-gate add %g2, %g3, %g2 ! normalize our current window if it's 6020Sstevel@tonic-gate add %g2, 1, %g2 ! less than zero 6030Sstevel@tonic-gate 6040Sstevel@tonic-gate ! note that while it's tempting, we can't execute restore to decrement 6050Sstevel@tonic-gate ! the %cwp by one (mod nwindows) because we're in the user's windows 6060Sstevel@tonic-gate1: 6070Sstevel@tonic-gate deccc %g2 ! decrement the current window 6080Sstevel@tonic-gate movl %xcc, %g3, %g2 ! normalize if it's negative (-1) 6090Sstevel@tonic-gate 6100Sstevel@tonic-gate wrpr %g2, %cwp ! change windows 6110Sstevel@tonic-gate 6120Sstevel@tonic-gate stx %i7, [%g1] ! stash the return address in pcstack 6130Sstevel@tonic-gate 6140Sstevel@tonic-gate deccc %g5 ! decrement the count 6150Sstevel@tonic-gate bnz,pt %icc, 1b ! we iterate until the count reaches 0 6160Sstevel@tonic-gate add %g1, 8, %g1 ! increment the pcstack pointer 6170Sstevel@tonic-gate 6180Sstevel@tonic-gate mov %i6, %g6 ! stash the last frame pointer we 6190Sstevel@tonic-gate ! encounter so the caller can 6200Sstevel@tonic-gate ! continue the stack walk in memory 6210Sstevel@tonic-gate 6220Sstevel@tonic-gate wrpr %g4, %cwp ! change back to the original window 6230Sstevel@tonic-gate 6240Sstevel@tonic-gate stn %g6, [%o2] ! return the last frame pointer 6250Sstevel@tonic-gate 6260Sstevel@tonic-gate2: 6270Sstevel@tonic-gate retl 6280Sstevel@tonic-gate nop 6290Sstevel@tonic-gate SET_SIZE(dtrace_getupcstack_top) 6300Sstevel@tonic-gate 6310Sstevel@tonic-gate#endif 6320Sstevel@tonic-gate 633191Sahl#if defined(lint) 634191Sahl 635191Sahl/*ARGSUSED*/ 636191Sahlint 637191Sahldtrace_getustackdepth_top(uintptr_t *sp) 638191Sahl{ return (0); } 639191Sahl 640191Sahl#else 641191Sahl 642191Sahl ENTRY(dtrace_getustackdepth_top) 643191Sahl mov %o0, %o2 644191Sahl rdpr %otherwin, %o0 645191Sahl 646191Sahl brlez,a,pn %o0, 2f ! return 0 if there are no user wins 647191Sahl clr %o0 648191Sahl 649191Sahl rdpr %cwp, %g4 ! remember our window so we can return 650191Sahl rdpr %canrestore, %g2 ! compute the first user window 651191Sahl sub %g4, %g2, %g2 ! current = %cwp - %canrestore - 652191Sahl subcc %g2, %o0, %g2 ! %otherwin 653191Sahl 654191Sahl bge,pt %xcc, 1f ! normalize the window if necessary 655191Sahl sethi %hi(nwin_minus_one), %g3 656191Sahl ld [%g3 + %lo(nwin_minus_one)], %g3 657191Sahl add %g2, %g3, %g2 658191Sahl add %g2, 1, %g2 659191Sahl 660191Sahl1: 661191Sahl wrpr %g2, %cwp ! change to the first user window 662191Sahl mov %i6, %g6 ! stash the frame pointer 663191Sahl wrpr %g4, %cwp ! change back to the original window 664191Sahl 665191Sahl stn %g6, [%o2] ! return the frame pointer 666191Sahl 667191Sahl2: 668191Sahl retl 669191Sahl nop 670191Sahl SET_SIZE(dtrace_getustackdepth_top) 671191Sahl 672191Sahl#endif 673191Sahl 6740Sstevel@tonic-gate#if defined(lint) || defined(__lint) 6750Sstevel@tonic-gate 6760Sstevel@tonic-gate/* ARGSUSED */ 6770Sstevel@tonic-gateulong_t 6780Sstevel@tonic-gatedtrace_getreg_win(uint_t reg, uint_t depth) 6790Sstevel@tonic-gate{ return (0); } 6800Sstevel@tonic-gate 6810Sstevel@tonic-gate#else /* lint */ 6820Sstevel@tonic-gate 6830Sstevel@tonic-gate ENTRY(dtrace_getreg_win) 6840Sstevel@tonic-gate sub %o0, 16, %o0 6850Sstevel@tonic-gate cmp %o0, 16 ! %o0 must begin in the range [16..32) 6860Sstevel@tonic-gate blu,pt %xcc, 1f 6870Sstevel@tonic-gate nop 6880Sstevel@tonic-gate retl 6890Sstevel@tonic-gate clr %o0 6900Sstevel@tonic-gate 6910Sstevel@tonic-gate1: 6920Sstevel@tonic-gate set dtrace_getreg_win_table, %g3 6930Sstevel@tonic-gate sll %o0, 2, %o0 6940Sstevel@tonic-gate add %g3, %o0, %g3 6950Sstevel@tonic-gate 6960Sstevel@tonic-gate rdpr %canrestore, %o3 6970Sstevel@tonic-gate rdpr %cwp, %g2 6980Sstevel@tonic-gate 6990Sstevel@tonic-gate ! Set %cwp to be (%cwp - %canrestore - %o1) mod NWINDOWS 7000Sstevel@tonic-gate 7010Sstevel@tonic-gate sub %g2, %o3, %o2 ! %o2 is %cwp - %canrestore 7020Sstevel@tonic-gate subcc %o2, %o1, %o4 7030Sstevel@tonic-gate bge,a,pn %xcc, 2f 7040Sstevel@tonic-gate wrpr %o4, %cwp 7050Sstevel@tonic-gate 7060Sstevel@tonic-gate sethi %hi(nwin_minus_one), %o3 7070Sstevel@tonic-gate ld [%o3 + %lo(nwin_minus_one)], %o3 7080Sstevel@tonic-gate 7090Sstevel@tonic-gate add %o2, %o3, %o4 7100Sstevel@tonic-gate wrpr %o4, %cwp 7110Sstevel@tonic-gate2: 7120Sstevel@tonic-gate jmp %g3 7130Sstevel@tonic-gate ba 3f 7140Sstevel@tonic-gate3: 7150Sstevel@tonic-gate wrpr %g2, %cwp 7160Sstevel@tonic-gate retl 7170Sstevel@tonic-gate mov %g1, %o0 7180Sstevel@tonic-gate 7190Sstevel@tonic-gatedtrace_getreg_win_table: 7200Sstevel@tonic-gate mov %l0, %g1 7210Sstevel@tonic-gate mov %l1, %g1 7220Sstevel@tonic-gate mov %l2, %g1 7230Sstevel@tonic-gate mov %l3, %g1 7240Sstevel@tonic-gate mov %l4, %g1 7250Sstevel@tonic-gate mov %l5, %g1 7260Sstevel@tonic-gate mov %l6, %g1 7270Sstevel@tonic-gate mov %l7, %g1 7280Sstevel@tonic-gate mov %i0, %g1 7290Sstevel@tonic-gate mov %i1, %g1 7300Sstevel@tonic-gate mov %i2, %g1 7310Sstevel@tonic-gate mov %i3, %g1 7320Sstevel@tonic-gate mov %i4, %g1 7330Sstevel@tonic-gate mov %i5, %g1 7340Sstevel@tonic-gate mov %i6, %g1 7350Sstevel@tonic-gate mov %i7, %g1 7360Sstevel@tonic-gate SET_SIZE(dtrace_getreg_win) 7370Sstevel@tonic-gate 7380Sstevel@tonic-gate#endif /* lint */ 7390Sstevel@tonic-gate 7400Sstevel@tonic-gate#if defined(lint) || defined(__lint) 7410Sstevel@tonic-gate 7420Sstevel@tonic-gate/* ARGSUSED */ 7430Sstevel@tonic-gatevoid 7440Sstevel@tonic-gatedtrace_putreg_win(uint_t reg, ulong_t value) 7450Sstevel@tonic-gate{} 7460Sstevel@tonic-gate 7470Sstevel@tonic-gate#else /* lint */ 7480Sstevel@tonic-gate 7490Sstevel@tonic-gate ENTRY(dtrace_putreg_win) 7500Sstevel@tonic-gate sub %o0, 16, %o0 7510Sstevel@tonic-gate cmp %o0, 16 ! %o0 must be in the range [16..32) 7520Sstevel@tonic-gate blu,pt %xcc, 1f 7530Sstevel@tonic-gate nop 7540Sstevel@tonic-gate retl 7550Sstevel@tonic-gate nop 7560Sstevel@tonic-gate 7570Sstevel@tonic-gate1: 7580Sstevel@tonic-gate mov %o1, %g1 ! move the value into a global register 7590Sstevel@tonic-gate 7600Sstevel@tonic-gate set dtrace_putreg_table, %g3 7610Sstevel@tonic-gate sll %o0, 2, %o0 7620Sstevel@tonic-gate add %g3, %o0, %g3 7630Sstevel@tonic-gate 7640Sstevel@tonic-gate rdpr %canrestore, %o3 7650Sstevel@tonic-gate rdpr %cwp, %g2 7660Sstevel@tonic-gate 7670Sstevel@tonic-gate ! Set %cwp to be (%cwp - %canrestore - 1) mod NWINDOWS 7680Sstevel@tonic-gate 7690Sstevel@tonic-gate sub %g2, %o3, %o2 ! %o2 is %cwp - %canrestore 7700Sstevel@tonic-gate subcc %o2, 1, %o4 7710Sstevel@tonic-gate bge,a,pn %xcc, 2f 7720Sstevel@tonic-gate wrpr %o4, %cwp 7730Sstevel@tonic-gate 7740Sstevel@tonic-gate sethi %hi(nwin_minus_one), %o3 7750Sstevel@tonic-gate ld [%o3 + %lo(nwin_minus_one)], %o3 7760Sstevel@tonic-gate add %o2, %o3, %o4 7770Sstevel@tonic-gate wrpr %o4, %cwp 7780Sstevel@tonic-gate2: 7790Sstevel@tonic-gate jmp %g3 7800Sstevel@tonic-gate ba 3f 7810Sstevel@tonic-gate3: 7820Sstevel@tonic-gate wrpr %g2, %cwp 7830Sstevel@tonic-gate retl 7840Sstevel@tonic-gate nop 7850Sstevel@tonic-gate 7860Sstevel@tonic-gatedtrace_putreg_table: 7870Sstevel@tonic-gate mov %g1, %l0 7880Sstevel@tonic-gate mov %g1, %l1 7890Sstevel@tonic-gate mov %g1, %l2 7900Sstevel@tonic-gate mov %g1, %l3 7910Sstevel@tonic-gate mov %g1, %l4 7920Sstevel@tonic-gate mov %g1, %l5 7930Sstevel@tonic-gate mov %g1, %l6 7940Sstevel@tonic-gate mov %g1, %l7 7950Sstevel@tonic-gate mov %g1, %i0 7960Sstevel@tonic-gate mov %g1, %i1 7970Sstevel@tonic-gate mov %g1, %i2 7980Sstevel@tonic-gate mov %g1, %i3 7990Sstevel@tonic-gate mov %g1, %i4 8000Sstevel@tonic-gate mov %g1, %i5 8010Sstevel@tonic-gate mov %g1, %i6 8020Sstevel@tonic-gate mov %g1, %i7 8030Sstevel@tonic-gate SET_SIZE(dtrace_putreg_win) 8040Sstevel@tonic-gate 8050Sstevel@tonic-gate#endif /* lint */ 8060Sstevel@tonic-gate 8070Sstevel@tonic-gate#if defined(lint) || defined(__lint) 8080Sstevel@tonic-gate 8090Sstevel@tonic-gate/*ARGSUSED*/ 8100Sstevel@tonic-gatevoid 8110Sstevel@tonic-gatedtrace_probe_error(dtrace_state_t *state, dtrace_epid_t epid, int which, 8120Sstevel@tonic-gate int fault, int fltoffs, uintptr_t illval) 8130Sstevel@tonic-gate{} 8140Sstevel@tonic-gate 8150Sstevel@tonic-gate#else /* lint */ 8160Sstevel@tonic-gate 8170Sstevel@tonic-gate ENTRY(dtrace_probe_error) 8180Sstevel@tonic-gate save %sp, -SA(MINFRAME), %sp 8190Sstevel@tonic-gate sethi %hi(dtrace_probeid_error), %l0 8200Sstevel@tonic-gate ld [%l0 + %lo(dtrace_probeid_error)], %o0 8210Sstevel@tonic-gate mov %i0, %o1 8220Sstevel@tonic-gate mov %i1, %o2 8230Sstevel@tonic-gate mov %i2, %o3 8240Sstevel@tonic-gate mov %i3, %o4 8250Sstevel@tonic-gate call dtrace_probe 8260Sstevel@tonic-gate mov %i4, %o5 8270Sstevel@tonic-gate ret 8280Sstevel@tonic-gate restore 8290Sstevel@tonic-gate SET_SIZE(dtrace_probe_error) 8300Sstevel@tonic-gate 8310Sstevel@tonic-gate#endif 832