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 2007 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #pragma ident "%Z%%M% %I% %E% SMI"
27
28 #if defined(lint) || defined(__lint)
29 #include <sys/dtrace_impl.h>
30 #else
31 #include <sys/asm_linkage.h>
32 #include <sys/privregs.h>
33 #include <sys/fsr.h>
34 #include <sys/asi.h>
35 #include "assym.h"
36 #endif
37
38 #if defined(lint) || defined(__lint)
39
40 int
41 dtrace_getipl(void)
42 { return (0); }
43
44 #else /* lint */
45
46 ENTRY_NP(dtrace_getipl)
47 retl
48 rdpr %pil, %o0
49 SET_SIZE(dtrace_getipl)
50
51 #endif /* lint */
52
53 #if defined(lint) || defined(__lint)
54
55 uint_t
56 dtrace_getotherwin(void)
57 { return (0); }
58
59 #else /* lint */
60
61 ENTRY_NP(dtrace_getotherwin)
62 retl
63 rdpr %otherwin, %o0
64 SET_SIZE(dtrace_getotherwin)
65
66 #endif /* lint */
67
68 #if defined(lint) || defined(__lint)
69
70 uint_t
71 dtrace_getfprs(void)
72 { return (0); }
73
74 #else /* lint */
75
76 ENTRY_NP(dtrace_getfprs)
77 retl
78 rd %fprs, %o0
79 SET_SIZE(dtrace_getfprs)
80
81 #endif /* lint */
82
83 #if defined(lint) || defined(__lint)
84
85 /*ARGSUSED*/
86 void
87 dtrace_getfsr(uint64_t *val)
88 {}
89
90 #else /* lint */
91
92 ENTRY_NP(dtrace_getfsr)
93 rdpr %pstate, %o1
94 andcc %o1, PSTATE_PEF, %g0
95 bz,pn %xcc, 1f
96 nop
97 rd %fprs, %o1
98 andcc %o1, FPRS_FEF, %g0
99 bz,pn %xcc, 1f
100 nop
101 retl
102 stx %fsr, [%o0]
103 1:
104 retl
105 stx %g0, [%o0]
106 SET_SIZE(dtrace_getfsr)
107
108 #endif /* lint */
109
110 #if defined(lint) || defined(__lint)
111
112 greg_t
113 dtrace_getfp(void)
114 { return (0); }
115
116 #else /* lint */
117
118 ENTRY_NP(dtrace_getfp)
119 retl
120 mov %fp, %o0
121 SET_SIZE(dtrace_getfp)
122
123 #endif /* lint */
124
125 #if defined(lint) || defined(__lint)
126
127 void
128 dtrace_flush_user_windows(void)
129 {}
130
131 #else
132
133 ENTRY_NP(dtrace_flush_user_windows)
134 rdpr %otherwin, %g1
135 brz %g1, 3f
136 clr %g2
137 1:
138 save %sp, -WINDOWSIZE, %sp
139 rdpr %otherwin, %g1
140 brnz %g1, 1b
141 add %g2, 1, %g2
142 2:
143 sub %g2, 1, %g2 ! restore back to orig window
144 brnz %g2, 2b
145 restore
146 3:
147 retl
148 nop
149 SET_SIZE(dtrace_flush_user_windows)
150
151 #endif /* lint */
152
153 #if defined(lint) || defined(__lint)
154
155 uint32_t
156 dtrace_cas32(uint32_t *target, uint32_t cmp, uint32_t new)
157 {
158 uint32_t old;
159
160 if ((old = *target) == cmp)
161 *target = new;
162 return (old);
163 }
164
165 void *
166 dtrace_casptr(void *target, void *cmp, void *new)
167 {
168 void *old;
169
170 if ((old = *(void **)target) == cmp)
171 *(void **)target = new;
172 return (old);
173 }
174
175 #else /* lint */
176
177 ENTRY(dtrace_cas32)
178 cas [%o0], %o1, %o2
179 retl
180 mov %o2, %o0
181 SET_SIZE(dtrace_cas32)
182
183 ENTRY(dtrace_casptr)
184 casn [%o0], %o1, %o2
185 retl
186 mov %o2, %o0
187 SET_SIZE(dtrace_casptr)
188
189 #endif /* lint */
190
191 #if defined(lint)
192
193 /*ARGSUSED*/
194 uintptr_t
195 dtrace_caller(int aframes)
196 {
197 return (0);
198 }
199
200 #else /* lint */
201
202 ENTRY(dtrace_caller)
203 sethi %hi(nwin_minus_one), %g4
204 ld [%g4 + %lo(nwin_minus_one)], %g4
205 rdpr %canrestore, %g2
206 cmp %g2, %o0
207 bl %icc, 1f
208 rdpr %cwp, %g1
209 sub %g1, %o0, %g3
210 brgez,a,pt %g3, 0f
211 wrpr %g3, %cwp
212
213 !
214 ! CWP minus the number of frames is negative; we must perform the
215 ! arithmetic modulo MAXWIN.
216 !
217 add %g4, %g3, %g3
218 inc %g3
219 wrpr %g3, %cwp
220 0:
221 mov %i7, %g4
222 wrpr %g1, %cwp
223 retl
224 mov %g4, %o0
225 1:
226 !
227 ! The caller has been flushed to the stack. This is unlikely
228 ! (interrupts are disabled in dtrace_probe()), but possible (the
229 ! interrupt inducing the spill may have been taken before the
230 ! call to dtrace_probe()).
231 !
232 retl
233 mov -1, %o0
234 SET_SIZE(dtrace_caller)
235
236 #endif
237
238 #if defined(lint)
239
240 /*ARGSUSED*/
241 int
242 dtrace_fish(int aframes, int reg, uintptr_t *regval)
243 {
244 return (0);
245 }
246
247 #else /* lint */
248
249 ENTRY(dtrace_fish)
250
251 rd %pc, %g5
252 ba 0f
253 add %g5, 12, %g5
254 mov %l0, %g4
255 mov %l1, %g4
256 mov %l2, %g4
257 mov %l3, %g4
258 mov %l4, %g4
259 mov %l5, %g4
260 mov %l6, %g4
261 mov %l7, %g4
262 mov %i0, %g4
263 mov %i1, %g4
264 mov %i2, %g4
265 mov %i3, %g4
266 mov %i4, %g4
267 mov %i5, %g4
268 mov %i6, %g4
294 add %g4, %g3, %g3
295 inc %g3
296 wrpr %g3, %cwp
297 0:
298 jmp %g5
299 ba 1f
300 1:
301 wrpr %g1, %cwp
302 stn %g4, [%o2]
303 retl
304 clr %o0 ! Success; return 0.
305 2:
306 !
307 ! The frame that we're looking for has been flushed to the stack; the
308 ! caller will be forced to
309 !
310 retl
311 add %g2, 1, %o0 ! Failure; return deepest frame + 1
312 SET_SIZE(dtrace_fish)
313
314 #endif
315
316 #if defined(lint)
317
318 /*ARGSUSED*/
319 void
320 dtrace_copyin(uintptr_t uaddr, uintptr_t kaddr, size_t size,
321 volatile uint16_t *flags)
322 {}
323
324 #else
325
326 ENTRY(dtrace_copyin)
327 tst %o2
328 bz 2f
329 clr %g1
330 lduba [%o0 + %g1]ASI_USER, %g2
331 0:
332 ! check for an error if the count is 4k-aligned
333 andcc %g1, 0xfff, %g0
334 bnz,pt %icc, 1f
335 stub %g2, [%o1 + %g1]
336 lduh [%o3], %g3
337 andcc %g3, CPU_DTRACE_BADADDR, %g0
338 bnz,pn %icc, 2f
339 nop
340 1:
341 inc %g1
342 cmp %g1, %o2
343 bl,a 0b
344 lduba [%o0 + %g1]ASI_USER, %g2
345 2:
346 retl
347 nop
348
349 SET_SIZE(dtrace_copyin)
350
351 #endif
352
353 #if defined(lint)
354
355 /*ARGSUSED*/
356 void
357 dtrace_copyinstr(uintptr_t uaddr, uintptr_t kaddr, size_t size,
358 volatile uint16_t *flags)
359 {}
360
361 #else
362
363 ENTRY(dtrace_copyinstr)
364 tst %o2
365 bz 2f
366 clr %g1
367 lduba [%o0 + %g1]ASI_USER, %g2
368 0:
369 stub %g2, [%o1 + %g1] ! Store byte
370
371 ! check for an error if the count is 4k-aligned
372 andcc %g1, 0xfff, %g0
373 bnz,pt %icc, 1f
374 inc %g1
375 lduh [%o3], %g3
376 andcc %g3, CPU_DTRACE_BADADDR, %g0
377 bnz,pn %icc, 2f
378 nop
379 1:
380 cmp %g2, 0 ! Was that '\0'?
381 be 2f ! If so, we're done
382 cmp %g1, %o2 ! Compare to limit
383 bl,a 0b ! If less, take another lap
384 lduba [%o0 + %g1]ASI_USER, %g2 ! delay: load user byte
385 2:
386 retl
387 nop
388
389 SET_SIZE(dtrace_copyinstr)
390
391 #endif
392
393 #if defined(lint)
394
395 /*ARGSUSED*/
396 void
397 dtrace_copyout(uintptr_t kaddr, uintptr_t uaddr, size_t size,
398 volatile uint16_t *flags)
399 {}
400
401 #else
402
403 ENTRY(dtrace_copyout)
404 tst %o2
405 bz 2f
406 clr %g1
407 ldub [%o0 + %g1], %g2
408 0:
409 ! check for an error if the count is 4k-aligned
410 andcc %g1, 0xfff, %g0
411 bnz,pt %icc, 1f
412 stba %g2, [%o1 + %g1]ASI_USER
413 lduh [%o3], %g3
414 andcc %g3, CPU_DTRACE_BADADDR, %g0
415 bnz,pn %icc, 2f
416 nop
417 1:
418 inc %g1
419 cmp %g1, %o2
420 bl,a 0b
421 ldub [%o0 + %g1], %g2
422 2:
423 retl
424 nop
425 SET_SIZE(dtrace_copyout)
426
427 #endif
428
429 #if defined(lint)
430
431 /*ARGSUSED*/
432 void
433 dtrace_copyoutstr(uintptr_t kaddr, uintptr_t uaddr, size_t size,
434 volatile uint16_t *flags)
435 {}
436
437 #else
438
439 ENTRY(dtrace_copyoutstr)
440 tst %o2
441 bz 2f
442 clr %g1
443 ldub [%o0 + %g1], %g2
444 0:
445 stba %g2, [%o1 + %g1]ASI_USER
446
447 ! check for an error if the count is 4k-aligned
448 andcc %g1, 0xfff, %g0
449 bnz,pt %icc, 1f
450 inc %g1
451 lduh [%o3], %g3
452 andcc %g3, CPU_DTRACE_BADADDR, %g0
453 bnz,pn %icc, 2f
454 nop
455 1:
456 cmp %g2, 0
457 be 2f
458 cmp %g1, %o2
459 bl,a 0b
460 ldub [%o0 + %g1], %g2
461 2:
462 retl
463 nop
464 SET_SIZE(dtrace_copyoutstr)
465
466 #endif
467
468 #if defined(lint)
469
470 /*ARGSUSED*/
471 uintptr_t
472 dtrace_fulword(void *addr)
473 { return (0); }
474
475 #else
476
477 ENTRY(dtrace_fulword)
478 clr %o1
479 ldna [%o0]ASI_USER, %o1
480 retl
481 mov %o1, %o0
482 SET_SIZE(dtrace_fulword)
483
484 #endif
485
486 #if defined(lint)
487
488 /*ARGSUSED*/
489 uint8_t
490 dtrace_fuword8(void *addr)
491 { return (0); }
492
493 #else
494
495 ENTRY(dtrace_fuword8)
496 clr %o1
497 lduba [%o0]ASI_USER, %o1
498 retl
499 mov %o1, %o0
500 SET_SIZE(dtrace_fuword8)
501
502 #endif
503
504 #if defined(lint)
505
506 /*ARGSUSED*/
507 uint16_t
508 dtrace_fuword16(void *addr)
509 { return (0); }
510
511 #else
512
513 ENTRY(dtrace_fuword16)
514 clr %o1
515 lduha [%o0]ASI_USER, %o1
516 retl
517 mov %o1, %o0
518 SET_SIZE(dtrace_fuword16)
519
520 #endif
521
522 #if defined(lint)
523
524 /*ARGSUSED*/
525 uint32_t
526 dtrace_fuword32(void *addr)
527 { return (0); }
528
529 #else
530
531 ENTRY(dtrace_fuword32)
532 clr %o1
533 lda [%o0]ASI_USER, %o1
534 retl
535 mov %o1, %o0
536 SET_SIZE(dtrace_fuword32)
537
538 #endif
539
540 #if defined(lint)
541
542 /*ARGSUSED*/
543 uint64_t
544 dtrace_fuword64(void *addr)
545 { return (0); }
546
547 #else
548
549 ENTRY(dtrace_fuword64)
550 clr %o1
551 ldxa [%o0]ASI_USER, %o1
552 retl
553 mov %o1, %o0
554 SET_SIZE(dtrace_fuword64)
555
556 #endif
557
558 #if defined(lint)
559
560 /*ARGSUSED*/
561 int
562 dtrace_getupcstack_top(uint64_t *pcstack, int pcstack_limit, uintptr_t *sp)
563 { return (0); }
564
565 #else
566
567 /*
568 * %g1 pcstack
569 * %g2 current window
570 * %g3 maxwin (nwindows - 1)
571 * %g4 saved %cwp (so we can get back to the original window)
572 * %g5 iteration count
573 * %g6 saved %fp
574 *
575 * %o0 pcstack / return value (iteration count)
576 * %o1 pcstack_limit
577 * %o2 last_fp
578 */
579
580 ENTRY(dtrace_getupcstack_top)
581 mov %o0, %g1 ! we need the pcstack pointer while
582 ! we're visiting other windows
583
584 rdpr %otherwin, %g5 ! compute the number of iterations
585 cmp %g5, %o1 ! (windows to observe) by taking the
586 movg %icc, %o1, %g5 ! min of %otherwin and pcstack_limit
611
612 stx %i7, [%g1] ! stash the return address in pcstack
613
614 deccc %g5 ! decrement the count
615 bnz,pt %icc, 1b ! we iterate until the count reaches 0
616 add %g1, 8, %g1 ! increment the pcstack pointer
617
618 mov %i6, %g6 ! stash the last frame pointer we
619 ! encounter so the caller can
620 ! continue the stack walk in memory
621
622 wrpr %g4, %cwp ! change back to the original window
623
624 stn %g6, [%o2] ! return the last frame pointer
625
626 2:
627 retl
628 nop
629 SET_SIZE(dtrace_getupcstack_top)
630
631 #endif
632
633 #if defined(lint)
634
635 /*ARGSUSED*/
636 int
637 dtrace_getustackdepth_top(uintptr_t *sp)
638 { return (0); }
639
640 #else
641
642 ENTRY(dtrace_getustackdepth_top)
643 mov %o0, %o2
644 rdpr %otherwin, %o0
645
646 brlez,a,pn %o0, 2f ! return 0 if there are no user wins
647 clr %o0
648
649 rdpr %cwp, %g4 ! remember our window so we can return
650 rdpr %canrestore, %g2 ! compute the first user window
651 sub %g4, %g2, %g2 ! current = %cwp - %canrestore -
652 subcc %g2, %o0, %g2 ! %otherwin
653
654 bge,pt %xcc, 1f ! normalize the window if necessary
655 sethi %hi(nwin_minus_one), %g3
656 ld [%g3 + %lo(nwin_minus_one)], %g3
657 add %g2, %g3, %g2
658 add %g2, 1, %g2
659
660 1:
661 wrpr %g2, %cwp ! change to the first user window
662 mov %i6, %g6 ! stash the frame pointer
663 wrpr %g4, %cwp ! change back to the original window
664
665 stn %g6, [%o2] ! return the frame pointer
666
667 2:
668 retl
669 nop
670 SET_SIZE(dtrace_getustackdepth_top)
671
672 #endif
673
674 #if defined(lint) || defined(__lint)
675
676 /* ARGSUSED */
677 ulong_t
678 dtrace_getreg_win(uint_t reg, uint_t depth)
679 { return (0); }
680
681 #else /* lint */
682
683 ENTRY(dtrace_getreg_win)
684 sub %o0, 16, %o0
685 cmp %o0, 16 ! %o0 must begin in the range [16..32)
686 blu,pt %xcc, 1f
687 nop
688 retl
689 clr %o0
690
691 1:
692 set dtrace_getreg_win_table, %g3
693 sll %o0, 2, %o0
694 add %g3, %o0, %g3
695
696 rdpr %canrestore, %o3
697 rdpr %cwp, %g2
698
699 ! Set %cwp to be (%cwp - %canrestore - %o1) mod NWINDOWS
700
701 sub %g2, %o3, %o2 ! %o2 is %cwp - %canrestore
702 subcc %o2, %o1, %o4
718
719 dtrace_getreg_win_table:
720 mov %l0, %g1
721 mov %l1, %g1
722 mov %l2, %g1
723 mov %l3, %g1
724 mov %l4, %g1
725 mov %l5, %g1
726 mov %l6, %g1
727 mov %l7, %g1
728 mov %i0, %g1
729 mov %i1, %g1
730 mov %i2, %g1
731 mov %i3, %g1
732 mov %i4, %g1
733 mov %i5, %g1
734 mov %i6, %g1
735 mov %i7, %g1
736 SET_SIZE(dtrace_getreg_win)
737
738 #endif /* lint */
739
740 #if defined(lint) || defined(__lint)
741
742 /* ARGSUSED */
743 void
744 dtrace_putreg_win(uint_t reg, ulong_t value)
745 {}
746
747 #else /* lint */
748
749 ENTRY(dtrace_putreg_win)
750 sub %o0, 16, %o0
751 cmp %o0, 16 ! %o0 must be in the range [16..32)
752 blu,pt %xcc, 1f
753 nop
754 retl
755 nop
756
757 1:
758 mov %o1, %g1 ! move the value into a global register
759
760 set dtrace_putreg_table, %g3
761 sll %o0, 2, %o0
762 add %g3, %o0, %g3
763
764 rdpr %canrestore, %o3
765 rdpr %cwp, %g2
766
767 ! Set %cwp to be (%cwp - %canrestore - 1) mod NWINDOWS
768
785
786 dtrace_putreg_table:
787 mov %g1, %l0
788 mov %g1, %l1
789 mov %g1, %l2
790 mov %g1, %l3
791 mov %g1, %l4
792 mov %g1, %l5
793 mov %g1, %l6
794 mov %g1, %l7
795 mov %g1, %i0
796 mov %g1, %i1
797 mov %g1, %i2
798 mov %g1, %i3
799 mov %g1, %i4
800 mov %g1, %i5
801 mov %g1, %i6
802 mov %g1, %i7
803 SET_SIZE(dtrace_putreg_win)
804
805 #endif /* lint */
806
807 #if defined(lint) || defined(__lint)
808
809 /*ARGSUSED*/
810 void
811 dtrace_probe_error(dtrace_state_t *state, dtrace_epid_t epid, int which,
812 int fault, int fltoffs, uintptr_t illval)
813 {}
814
815 #else /* lint */
816
817 ENTRY(dtrace_probe_error)
818 save %sp, -SA(MINFRAME), %sp
819 sethi %hi(dtrace_probeid_error), %l0
820 ld [%l0 + %lo(dtrace_probeid_error)], %o0
821 mov %i0, %o1
822 mov %i1, %o2
823 mov %i2, %o3
824 mov %i3, %o4
825 call dtrace_probe
826 mov %i4, %o5
827 ret
828 restore
829 SET_SIZE(dtrace_probe_error)
830
831 #endif
|
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 2007 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #include <sys/asm_linkage.h>
27 #include <sys/privregs.h>
28 #include <sys/fsr.h>
29 #include <sys/asi.h>
30 #include "assym.h"
31
32 ENTRY_NP(dtrace_getipl)
33 retl
34 rdpr %pil, %o0
35 SET_SIZE(dtrace_getipl)
36
37 ENTRY_NP(dtrace_getotherwin)
38 retl
39 rdpr %otherwin, %o0
40 SET_SIZE(dtrace_getotherwin)
41
42 ENTRY_NP(dtrace_getfprs)
43 retl
44 rd %fprs, %o0
45 SET_SIZE(dtrace_getfprs)
46
47 ENTRY_NP(dtrace_getfsr)
48 rdpr %pstate, %o1
49 andcc %o1, PSTATE_PEF, %g0
50 bz,pn %xcc, 1f
51 nop
52 rd %fprs, %o1
53 andcc %o1, FPRS_FEF, %g0
54 bz,pn %xcc, 1f
55 nop
56 retl
57 stx %fsr, [%o0]
58 1:
59 retl
60 stx %g0, [%o0]
61 SET_SIZE(dtrace_getfsr)
62
63 ENTRY_NP(dtrace_getfp)
64 retl
65 mov %fp, %o0
66 SET_SIZE(dtrace_getfp)
67
68 ENTRY_NP(dtrace_flush_user_windows)
69 rdpr %otherwin, %g1
70 brz %g1, 3f
71 clr %g2
72 1:
73 save %sp, -WINDOWSIZE, %sp
74 rdpr %otherwin, %g1
75 brnz %g1, 1b
76 add %g2, 1, %g2
77 2:
78 sub %g2, 1, %g2 ! restore back to orig window
79 brnz %g2, 2b
80 restore
81 3:
82 retl
83 nop
84 SET_SIZE(dtrace_flush_user_windows)
85
86 ENTRY(dtrace_cas32)
87 cas [%o0], %o1, %o2
88 retl
89 mov %o2, %o0
90 SET_SIZE(dtrace_cas32)
91
92 ENTRY(dtrace_casptr)
93 casn [%o0], %o1, %o2
94 retl
95 mov %o2, %o0
96 SET_SIZE(dtrace_casptr)
97
98 ENTRY(dtrace_caller)
99 sethi %hi(nwin_minus_one), %g4
100 ld [%g4 + %lo(nwin_minus_one)], %g4
101 rdpr %canrestore, %g2
102 cmp %g2, %o0
103 bl %icc, 1f
104 rdpr %cwp, %g1
105 sub %g1, %o0, %g3
106 brgez,a,pt %g3, 0f
107 wrpr %g3, %cwp
108
109 !
110 ! CWP minus the number of frames is negative; we must perform the
111 ! arithmetic modulo MAXWIN.
112 !
113 add %g4, %g3, %g3
114 inc %g3
115 wrpr %g3, %cwp
116 0:
117 mov %i7, %g4
118 wrpr %g1, %cwp
119 retl
120 mov %g4, %o0
121 1:
122 !
123 ! The caller has been flushed to the stack. This is unlikely
124 ! (interrupts are disabled in dtrace_probe()), but possible (the
125 ! interrupt inducing the spill may have been taken before the
126 ! call to dtrace_probe()).
127 !
128 retl
129 mov -1, %o0
130 SET_SIZE(dtrace_caller)
131
132 ENTRY(dtrace_fish)
133
134 rd %pc, %g5
135 ba 0f
136 add %g5, 12, %g5
137 mov %l0, %g4
138 mov %l1, %g4
139 mov %l2, %g4
140 mov %l3, %g4
141 mov %l4, %g4
142 mov %l5, %g4
143 mov %l6, %g4
144 mov %l7, %g4
145 mov %i0, %g4
146 mov %i1, %g4
147 mov %i2, %g4
148 mov %i3, %g4
149 mov %i4, %g4
150 mov %i5, %g4
151 mov %i6, %g4
177 add %g4, %g3, %g3
178 inc %g3
179 wrpr %g3, %cwp
180 0:
181 jmp %g5
182 ba 1f
183 1:
184 wrpr %g1, %cwp
185 stn %g4, [%o2]
186 retl
187 clr %o0 ! Success; return 0.
188 2:
189 !
190 ! The frame that we're looking for has been flushed to the stack; the
191 ! caller will be forced to
192 !
193 retl
194 add %g2, 1, %o0 ! Failure; return deepest frame + 1
195 SET_SIZE(dtrace_fish)
196
197 ENTRY(dtrace_copyin)
198 tst %o2
199 bz 2f
200 clr %g1
201 lduba [%o0 + %g1]ASI_USER, %g2
202 0:
203 ! check for an error if the count is 4k-aligned
204 andcc %g1, 0xfff, %g0
205 bnz,pt %icc, 1f
206 stub %g2, [%o1 + %g1]
207 lduh [%o3], %g3
208 andcc %g3, CPU_DTRACE_BADADDR, %g0
209 bnz,pn %icc, 2f
210 nop
211 1:
212 inc %g1
213 cmp %g1, %o2
214 bl,a 0b
215 lduba [%o0 + %g1]ASI_USER, %g2
216 2:
217 retl
218 nop
219
220 SET_SIZE(dtrace_copyin)
221
222 ENTRY(dtrace_copyinstr)
223 tst %o2
224 bz 2f
225 clr %g1
226 lduba [%o0 + %g1]ASI_USER, %g2
227 0:
228 stub %g2, [%o1 + %g1] ! Store byte
229
230 ! check for an error if the count is 4k-aligned
231 andcc %g1, 0xfff, %g0
232 bnz,pt %icc, 1f
233 inc %g1
234 lduh [%o3], %g3
235 andcc %g3, CPU_DTRACE_BADADDR, %g0
236 bnz,pn %icc, 2f
237 nop
238 1:
239 cmp %g2, 0 ! Was that '\0'?
240 be 2f ! If so, we're done
241 cmp %g1, %o2 ! Compare to limit
242 bl,a 0b ! If less, take another lap
243 lduba [%o0 + %g1]ASI_USER, %g2 ! delay: load user byte
244 2:
245 retl
246 nop
247
248 SET_SIZE(dtrace_copyinstr)
249
250 ENTRY(dtrace_copyout)
251 tst %o2
252 bz 2f
253 clr %g1
254 ldub [%o0 + %g1], %g2
255 0:
256 ! check for an error if the count is 4k-aligned
257 andcc %g1, 0xfff, %g0
258 bnz,pt %icc, 1f
259 stba %g2, [%o1 + %g1]ASI_USER
260 lduh [%o3], %g3
261 andcc %g3, CPU_DTRACE_BADADDR, %g0
262 bnz,pn %icc, 2f
263 nop
264 1:
265 inc %g1
266 cmp %g1, %o2
267 bl,a 0b
268 ldub [%o0 + %g1], %g2
269 2:
270 retl
271 nop
272 SET_SIZE(dtrace_copyout)
273
274 ENTRY(dtrace_copyoutstr)
275 tst %o2
276 bz 2f
277 clr %g1
278 ldub [%o0 + %g1], %g2
279 0:
280 stba %g2, [%o1 + %g1]ASI_USER
281
282 ! check for an error if the count is 4k-aligned
283 andcc %g1, 0xfff, %g0
284 bnz,pt %icc, 1f
285 inc %g1
286 lduh [%o3], %g3
287 andcc %g3, CPU_DTRACE_BADADDR, %g0
288 bnz,pn %icc, 2f
289 nop
290 1:
291 cmp %g2, 0
292 be 2f
293 cmp %g1, %o2
294 bl,a 0b
295 ldub [%o0 + %g1], %g2
296 2:
297 retl
298 nop
299 SET_SIZE(dtrace_copyoutstr)
300
301 ENTRY(dtrace_fulword)
302 clr %o1
303 ldna [%o0]ASI_USER, %o1
304 retl
305 mov %o1, %o0
306 SET_SIZE(dtrace_fulword)
307
308 ENTRY(dtrace_fuword8)
309 clr %o1
310 lduba [%o0]ASI_USER, %o1
311 retl
312 mov %o1, %o0
313 SET_SIZE(dtrace_fuword8)
314
315 ENTRY(dtrace_fuword16)
316 clr %o1
317 lduha [%o0]ASI_USER, %o1
318 retl
319 mov %o1, %o0
320 SET_SIZE(dtrace_fuword16)
321
322 ENTRY(dtrace_fuword32)
323 clr %o1
324 lda [%o0]ASI_USER, %o1
325 retl
326 mov %o1, %o0
327 SET_SIZE(dtrace_fuword32)
328
329 ENTRY(dtrace_fuword64)
330 clr %o1
331 ldxa [%o0]ASI_USER, %o1
332 retl
333 mov %o1, %o0
334 SET_SIZE(dtrace_fuword64)
335
336 /*
337 * %g1 pcstack
338 * %g2 current window
339 * %g3 maxwin (nwindows - 1)
340 * %g4 saved %cwp (so we can get back to the original window)
341 * %g5 iteration count
342 * %g6 saved %fp
343 *
344 * %o0 pcstack / return value (iteration count)
345 * %o1 pcstack_limit
346 * %o2 last_fp
347 */
348
349 ENTRY(dtrace_getupcstack_top)
350 mov %o0, %g1 ! we need the pcstack pointer while
351 ! we're visiting other windows
352
353 rdpr %otherwin, %g5 ! compute the number of iterations
354 cmp %g5, %o1 ! (windows to observe) by taking the
355 movg %icc, %o1, %g5 ! min of %otherwin and pcstack_limit
380
381 stx %i7, [%g1] ! stash the return address in pcstack
382
383 deccc %g5 ! decrement the count
384 bnz,pt %icc, 1b ! we iterate until the count reaches 0
385 add %g1, 8, %g1 ! increment the pcstack pointer
386
387 mov %i6, %g6 ! stash the last frame pointer we
388 ! encounter so the caller can
389 ! continue the stack walk in memory
390
391 wrpr %g4, %cwp ! change back to the original window
392
393 stn %g6, [%o2] ! return the last frame pointer
394
395 2:
396 retl
397 nop
398 SET_SIZE(dtrace_getupcstack_top)
399
400 ENTRY(dtrace_getustackdepth_top)
401 mov %o0, %o2
402 rdpr %otherwin, %o0
403
404 brlez,a,pn %o0, 2f ! return 0 if there are no user wins
405 clr %o0
406
407 rdpr %cwp, %g4 ! remember our window so we can return
408 rdpr %canrestore, %g2 ! compute the first user window
409 sub %g4, %g2, %g2 ! current = %cwp - %canrestore -
410 subcc %g2, %o0, %g2 ! %otherwin
411
412 bge,pt %xcc, 1f ! normalize the window if necessary
413 sethi %hi(nwin_minus_one), %g3
414 ld [%g3 + %lo(nwin_minus_one)], %g3
415 add %g2, %g3, %g2
416 add %g2, 1, %g2
417
418 1:
419 wrpr %g2, %cwp ! change to the first user window
420 mov %i6, %g6 ! stash the frame pointer
421 wrpr %g4, %cwp ! change back to the original window
422
423 stn %g6, [%o2] ! return the frame pointer
424
425 2:
426 retl
427 nop
428 SET_SIZE(dtrace_getustackdepth_top)
429
430 ENTRY(dtrace_getreg_win)
431 sub %o0, 16, %o0
432 cmp %o0, 16 ! %o0 must begin in the range [16..32)
433 blu,pt %xcc, 1f
434 nop
435 retl
436 clr %o0
437
438 1:
439 set dtrace_getreg_win_table, %g3
440 sll %o0, 2, %o0
441 add %g3, %o0, %g3
442
443 rdpr %canrestore, %o3
444 rdpr %cwp, %g2
445
446 ! Set %cwp to be (%cwp - %canrestore - %o1) mod NWINDOWS
447
448 sub %g2, %o3, %o2 ! %o2 is %cwp - %canrestore
449 subcc %o2, %o1, %o4
465
466 dtrace_getreg_win_table:
467 mov %l0, %g1
468 mov %l1, %g1
469 mov %l2, %g1
470 mov %l3, %g1
471 mov %l4, %g1
472 mov %l5, %g1
473 mov %l6, %g1
474 mov %l7, %g1
475 mov %i0, %g1
476 mov %i1, %g1
477 mov %i2, %g1
478 mov %i3, %g1
479 mov %i4, %g1
480 mov %i5, %g1
481 mov %i6, %g1
482 mov %i7, %g1
483 SET_SIZE(dtrace_getreg_win)
484
485 ENTRY(dtrace_putreg_win)
486 sub %o0, 16, %o0
487 cmp %o0, 16 ! %o0 must be in the range [16..32)
488 blu,pt %xcc, 1f
489 nop
490 retl
491 nop
492
493 1:
494 mov %o1, %g1 ! move the value into a global register
495
496 set dtrace_putreg_table, %g3
497 sll %o0, 2, %o0
498 add %g3, %o0, %g3
499
500 rdpr %canrestore, %o3
501 rdpr %cwp, %g2
502
503 ! Set %cwp to be (%cwp - %canrestore - 1) mod NWINDOWS
504
521
522 dtrace_putreg_table:
523 mov %g1, %l0
524 mov %g1, %l1
525 mov %g1, %l2
526 mov %g1, %l3
527 mov %g1, %l4
528 mov %g1, %l5
529 mov %g1, %l6
530 mov %g1, %l7
531 mov %g1, %i0
532 mov %g1, %i1
533 mov %g1, %i2
534 mov %g1, %i3
535 mov %g1, %i4
536 mov %g1, %i5
537 mov %g1, %i6
538 mov %g1, %i7
539 SET_SIZE(dtrace_putreg_win)
540
541 ENTRY(dtrace_probe_error)
542 save %sp, -SA(MINFRAME), %sp
543 sethi %hi(dtrace_probeid_error), %l0
544 ld [%l0 + %lo(dtrace_probeid_error)], %o0
545 mov %i0, %o1
546 mov %i1, %o2
547 mov %i2, %o3
548 mov %i3, %o4
549 call dtrace_probe
550 mov %i4, %o5
551 ret
552 restore
553 SET_SIZE(dtrace_probe_error)
554
|