dtrace_asm.S revision 246275
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License").  You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 *
22 * Portions Copyright 2012,2013 Justin Hibbits <jhibbits@freebsd.org>
23 *
24 * $FreeBSD: head/sys/cddl/dev/dtrace/powerpc/dtrace_asm.S 246275 2013-02-03 00:19:34Z jhibbits $
25 */
26/*
27 * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
28 * Use is subject to license terms.
29 */
30
31#include "assym.s"
32
33#define _ASM
34
35#include <sys/cpuvar_defs.h>
36#include <sys/dtrace.h>
37
38#include <machine/asm.h>
39/*
40#include <machine/cpu.h>
41*/
42
43/*
44 * Primitives
45 */
46
47        .text
48
49/*
50void dtrace_membar_producer(void)
51*/
52ASENTRY_NOPROF(dtrace_membar_producer)
53	blr
54END(dtrace_membar_producer)
55
56/*
57void dtrace_membar_consumer(void)
58*/
59ASENTRY_NOPROF(dtrace_membar_consumer)
60	blr
61END(dtrace_membar_consumer)
62
63/*
64dtrace_icookie_t dtrace_interrupt_disable(void)
65*/
66ASENTRY_NOPROF(dtrace_interrupt_disable)
67	mfmsr	%r3
68	andi.	%r0,%r3,~PSL_EE@l
69	mtmsr	%r0
70	blr
71END(dtrace_interrupt_disable)
72
73/*
74void dtrace_interrupt_enable(dtrace_icookie_t cookie)
75*/
76ASENTRY_NOPROF(dtrace_interrupt_enable)
77	mtmsr	%r3
78	blr
79END(dtrace_interrupt_enable)
80
81/*
82uint32_t dtrace_cas32(uint32_t *target, uint32_t cmp, uint32_t new)
83*/
84ASENTRY_NOPROF(dtrace_cas32)
851:
86	lwarx	%r0,0,%r3
87	cmpw	%r4,%r0
88	bne		2f
89	stwcx.	%r5,0,%r3
90	bne		1b
912:	mr		%r3,%r0
92	blr
93END(dtrace_cas32)
94
95/*
96void *
97dtrace_casptr(void *target, void *cmp, void *new)
98*/
99ASENTRY_NOPROF(dtrace_casptr)
1001:
101	lwarx	%r0,0,%r3
102	cmpw	%r4,%r0
103	bne		2f
104	stwcx.	%r5,0,%r3
105	bne		1b
1062:	mr		%r3,%r0
107	blr
108END(dtrace_casptr)
109
110
111/*
112uintptr_t
113dtrace_fulword(void *addr)
114*/
115ASENTRY_NOPROF(dtrace_fulword)
116END(dtrace_fulword)
117
118/*
119XXX: unoptimized
120void
121dtrace_copy(uintptr_t src, uintptr_t dest, size_t size)
122*/
123ASENTRY_NOPROF(dtrace_copy)
124	addme	%r7,%r3
125	addme	%r8,%r4
1261:
127	lbzu	%r3,1(%r7)
128	stbu	%r3,1(%r8)
129	addme	%r5,%r5
130	beq		2f
1312:
132	blr
133END(dtrace_copy)
134
135/*
136void
137dtrace_copystr(uintptr_t uaddr, uintptr_t kaddr, size_t size,
138    volatile uint16_t *flags)
139*/
140ASENTRY_NOPROF(dtrace_copystr)
141	addme	%r7,%r3
142	addme	%r8,%r4
1431:
144	lbzu	%r3,1(%r7)
145	stbu	%r3,1(%r8)
146	addme	%r5,%r5
147	beq		2f
148	or		%r3,%r3,%r3
149	beq		2f
150	andi.	%r0,%r5,0x0fff
151	beq		2f
152	lwz		%r0,0(%r6)
153	andi.	%r0,%r0,CPU_DTRACE_BADADDR
154	beq		1b
1552:
156	blr
157END(dtrace_copystr)
158
159/*
160void dtrace_invop_init(void)
161*/
162ASENTRY_NOPROF(dtrace_invop_init)
163	/* XXX: impement it properly -- implement dtrace_invop_start */
164	li		%r0,0
165	li		%r3,dtrace_invop_jump_addr@l
166	addis	%r3,%r3,dtrace_invop_jump_addr@ha
167	stw		%r0,0(%r3)
168	blr
169END(dtrace_invop_init)
170
171/*
172void dtrace_invop_uninit(void)
173*/
174ASENTRY_NOPROF(dtrace_invop_uninit)
175	li		%r0,0
176	li		%r3,dtrace_invop_jump_addr@l
177	addis	%r3,%r3,dtrace_invop_jump_addr@ha
178	stw		%r0,0(%r3)
179	blr
180END(dtrace_invop_uninit)
181
182/*
183 * The panic() and cmn_err() functions invoke vpanic() as a common entry point
184 * into the panic code implemented in panicsys().  vpanic() is responsible
185 * for passing through the format string and arguments, and constructing a
186 * regs structure on the stack into which it saves the current register
187 * values.  If we are not dying due to a fatal trap, these registers will
188 * then be preserved in panicbuf as the current processor state.  Before
189 * invoking panicsys(), vpanic() activates the first panic trigger (see
190 * common/os/panic.c) and switches to the panic_stack if successful.  Note that
191 * DTrace takes a slightly different panic path if it must panic from probe
192 * context.  Instead of calling panic, it calls into dtrace_vpanic(), which
193 * sets up the initial stack as vpanic does, calls dtrace_panic_trigger(), and
194 * branches back into vpanic().
195 */
196
197/*
198void
199vpanic(const char *format, va_list alist)
200*/
201ASENTRY_NOPROF(vpanic)				/* Initial stack layout: */
202
203vpanic_common:
204	blr
205END(vpanic)
206
207
208
209/*
210void
211dtrace_vpanic(const char *format, va_list alist)
212*/
213ASENTRY_NOPROF(dtrace_vpanic)			/* Initial stack layout: */
214
215#if 0
216	bl	dtrace_panic_trigger	/* %eax = dtrace_panic_trigger() */
217#endif
218	b	vpanic_common
219END(dtrace_vpanic)
220
221/*
222uintptr_t
223dtrace_caller(int aframes)
224*/
225ASENTRY_NOPROF(dtrace_caller)
226	li	%r3, -1
227	blr
228END(dtrace_caller)
229
230