xref: /titanic_52/usr/src/uts/sparc/fs/proc/prmachdep.c (revision b02e9a2d4d2071d770e5aa9ae8f83f2bbe1f2ced)
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 /*
23  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
28 /*	  All Rights Reserved  	*/
29 
30 
31 #pragma ident	"%Z%%M%	%I%	%E% SMI"	/* SVr4.0 1.8 */
32 
33 #include <sys/types.h>
34 #include <sys/t_lock.h>
35 #include <sys/param.h>
36 #include <sys/cred.h>
37 #include <sys/debug.h>
38 #include <sys/inline.h>
39 #include <sys/kmem.h>
40 #include <sys/proc.h>
41 #include <sys/sysmacros.h>
42 #include <sys/systm.h>
43 #include <sys/vmsystm.h>
44 #include <sys/vfs.h>
45 #include <sys/vnode.h>
46 #include <sys/pcb.h>
47 #include <sys/buf.h>
48 #include <sys/signal.h>
49 #include <sys/user.h>
50 #include <sys/cpuvar.h>
51 #include <sys/copyops.h>
52 #include <sys/watchpoint.h>
53 
54 #include <sys/fault.h>
55 #include <sys/syscall.h>
56 #include <sys/procfs.h>
57 #include <sys/archsystm.h>
58 #include <sys/cmn_err.h>
59 #include <sys/stack.h>
60 #include <sys/machpcb.h>
61 #include <sys/simulate.h>
62 #include <sys/fpu/fpusystm.h>
63 
64 #include <sys/pte.h>
65 #include <sys/vmem.h>
66 #include <sys/mman.h>
67 #include <sys/vmparam.h>
68 #include <vm/hat.h>
69 #include <vm/as.h>
70 #include <vm/seg.h>
71 #include <vm/seg_kmem.h>
72 #include <vm/seg_kp.h>
73 #include <vm/page.h>
74 
75 #include <fs/proc/prdata.h>
76 #include <v9/sys/psr_compat.h>
77 
78 int	prnwatch = 10000;	/* maximum number of watched areas */
79 
80 /*
81  * Force a thread into the kernel if it is not already there.
82  * This is a no-op on uniprocessors.
83  */
84 /* ARGSUSED */
85 void
86 prpokethread(kthread_t *t)
87 {
88 	if (t->t_state == TS_ONPROC && t->t_cpu != CPU)
89 		poke_cpu(t->t_cpu->cpu_id);
90 }
91 
92 /*
93  * Return general registers.
94  */
95 void
96 prgetprregs(klwp_t *lwp, prgregset_t prp)
97 {
98 	gregset_t gr;
99 
100 	ASSERT(MUTEX_NOT_HELD(&lwptoproc(lwp)->p_lock));
101 
102 	getgregs(lwp, gr);
103 	bzero(prp, sizeof (prp));
104 
105 	/*
106 	 * Can't copy since prgregset_t and gregset_t
107 	 * use different defines.
108 	 */
109 	prp[R_G1] = gr[REG_G1];
110 	prp[R_G2] = gr[REG_G2];
111 	prp[R_G3] = gr[REG_G3];
112 	prp[R_G4] = gr[REG_G4];
113 	prp[R_G5] = gr[REG_G5];
114 	prp[R_G6] = gr[REG_G6];
115 	prp[R_G7] = gr[REG_G7];
116 
117 	prp[R_O0] = gr[REG_O0];
118 	prp[R_O1] = gr[REG_O1];
119 	prp[R_O2] = gr[REG_O2];
120 	prp[R_O3] = gr[REG_O3];
121 	prp[R_O4] = gr[REG_O4];
122 	prp[R_O5] = gr[REG_O5];
123 	prp[R_O6] = gr[REG_O6];
124 	prp[R_O7] = gr[REG_O7];
125 
126 	if (lwp->lwp_pcb.pcb_xregstat != XREGNONE) {
127 		prp[R_L0] = lwp->lwp_pcb.pcb_xregs.rw_local[0];
128 		prp[R_L1] = lwp->lwp_pcb.pcb_xregs.rw_local[1];
129 		prp[R_L2] = lwp->lwp_pcb.pcb_xregs.rw_local[2];
130 		prp[R_L3] = lwp->lwp_pcb.pcb_xregs.rw_local[3];
131 		prp[R_L4] = lwp->lwp_pcb.pcb_xregs.rw_local[4];
132 		prp[R_L5] = lwp->lwp_pcb.pcb_xregs.rw_local[5];
133 		prp[R_L6] = lwp->lwp_pcb.pcb_xregs.rw_local[6];
134 		prp[R_L7] = lwp->lwp_pcb.pcb_xregs.rw_local[7];
135 
136 		prp[R_I0] = lwp->lwp_pcb.pcb_xregs.rw_in[0];
137 		prp[R_I1] = lwp->lwp_pcb.pcb_xregs.rw_in[1];
138 		prp[R_I2] = lwp->lwp_pcb.pcb_xregs.rw_in[2];
139 		prp[R_I3] = lwp->lwp_pcb.pcb_xregs.rw_in[3];
140 		prp[R_I4] = lwp->lwp_pcb.pcb_xregs.rw_in[4];
141 		prp[R_I5] = lwp->lwp_pcb.pcb_xregs.rw_in[5];
142 		prp[R_I6] = lwp->lwp_pcb.pcb_xregs.rw_in[6];
143 		prp[R_I7] = lwp->lwp_pcb.pcb_xregs.rw_in[7];
144 	}
145 
146 	prp[R_CCR] = gr[REG_CCR];
147 	prp[R_ASI] = gr[REG_ASI];
148 	prp[R_FPRS] = gr[REG_FPRS];
149 	prp[R_PC]  = gr[REG_PC];
150 	prp[R_nPC] = gr[REG_nPC];
151 	prp[R_Y]   = gr[REG_Y];
152 }
153 
154 /*
155  * Set general registers.
156  */
157 void
158 prsetprregs(klwp_t *lwp, prgregset_t prp, int initial)
159 {
160 	gregset_t gr;
161 
162 	gr[REG_G1] = prp[R_G1];
163 	gr[REG_G2] = prp[R_G2];
164 	gr[REG_G3] = prp[R_G3];
165 	gr[REG_G4] = prp[R_G4];
166 	gr[REG_G5] = prp[R_G5];
167 	gr[REG_G6] = prp[R_G6];
168 	gr[REG_G7] = prp[R_G7];
169 
170 	gr[REG_O0] = prp[R_O0];
171 	gr[REG_O1] = prp[R_O1];
172 	gr[REG_O2] = prp[R_O2];
173 	gr[REG_O3] = prp[R_O3];
174 	gr[REG_O4] = prp[R_O4];
175 	gr[REG_O5] = prp[R_O5];
176 	gr[REG_O6] = prp[R_O6];
177 	gr[REG_O7] = prp[R_O7];
178 
179 	lwp->lwp_pcb.pcb_xregs.rw_local[0] = prp[R_L0];
180 	lwp->lwp_pcb.pcb_xregs.rw_local[1] = prp[R_L1];
181 	lwp->lwp_pcb.pcb_xregs.rw_local[2] = prp[R_L2];
182 	lwp->lwp_pcb.pcb_xregs.rw_local[3] = prp[R_L3];
183 	lwp->lwp_pcb.pcb_xregs.rw_local[4] = prp[R_L4];
184 	lwp->lwp_pcb.pcb_xregs.rw_local[5] = prp[R_L5];
185 	lwp->lwp_pcb.pcb_xregs.rw_local[6] = prp[R_L6];
186 	lwp->lwp_pcb.pcb_xregs.rw_local[7] = prp[R_L7];
187 
188 	lwp->lwp_pcb.pcb_xregs.rw_in[0] = prp[R_I0];
189 	lwp->lwp_pcb.pcb_xregs.rw_in[1] = prp[R_I1];
190 	lwp->lwp_pcb.pcb_xregs.rw_in[2] = prp[R_I2];
191 	lwp->lwp_pcb.pcb_xregs.rw_in[3] = prp[R_I3];
192 	lwp->lwp_pcb.pcb_xregs.rw_in[4] = prp[R_I4];
193 	lwp->lwp_pcb.pcb_xregs.rw_in[5] = prp[R_I5];
194 	lwp->lwp_pcb.pcb_xregs.rw_in[6] = prp[R_I6];
195 	lwp->lwp_pcb.pcb_xregs.rw_in[7] = prp[R_I7];
196 
197 	lwp->lwp_pcb.pcb_xregstat = XREGMODIFIED;
198 	lwptot(lwp)->t_post_sys = 1;
199 
200 	/*
201 	 * setgregs will only allow the condition codes to be set.
202 	 */
203 	gr[REG_CCR] = prp[R_CCR];
204 	gr[REG_ASI] = prp[R_ASI];
205 	gr[REG_FPRS] = prp[R_FPRS];
206 	gr[REG_PC]  = prp[R_PC];
207 	gr[REG_nPC] = prp[R_nPC];
208 	gr[REG_Y]   = prp[R_Y];
209 
210 	if (initial) {		/* set initial values */
211 		if (lwptoproc(lwp)->p_model == DATAMODEL_LP64)
212 			lwptoregs(lwp)->r_tstate = TSTATE_USER64;
213 		else
214 			lwptoregs(lwp)->r_tstate = TSTATE_USER32;
215 		if (!fpu_exists)
216 			lwptoregs(lwp)->r_tstate &= ~TSTATE_PEF;
217 	}
218 
219 	setgregs(lwp, gr);
220 }
221 
222 #ifdef _SYSCALL32_IMPL
223 
224 /*
225  * modify the lower 32bits of a uint64_t
226  */
227 #define	SET_LOWER_32(all, lower)	\
228 	(((uint64_t)(all) & 0xffffffff00000000) | (uint32_t)(lower))
229 
230 /*
231  * Convert prgregset32 to native prgregset.
232  */
233 void
234 prgregset_32ton(klwp_t *lwp, prgregset32_t src, prgregset_t dest)
235 {
236 	struct regs *r = lwptoregs(lwp);
237 
238 	dest[R_G0] = SET_LOWER_32(0, src[R_G0]);
239 	dest[R_G1] = SET_LOWER_32(r->r_g1, src[R_G1]);
240 	dest[R_G2] = SET_LOWER_32(r->r_g2, src[R_G2]);
241 	dest[R_G3] = SET_LOWER_32(r->r_g3, src[R_G3]);
242 	dest[R_G4] = SET_LOWER_32(r->r_g4, src[R_G4]);
243 	dest[R_G5] = SET_LOWER_32(r->r_g5, src[R_G5]);
244 	dest[R_G6] = SET_LOWER_32(r->r_g6, src[R_G6]);
245 	dest[R_G7] = SET_LOWER_32(r->r_g7, src[R_G7]);
246 
247 	dest[R_O0] = SET_LOWER_32(r->r_o0, src[R_O0]);
248 	dest[R_O1] = SET_LOWER_32(r->r_o1, src[R_O1]);
249 	dest[R_O2] = SET_LOWER_32(r->r_o2, src[R_O2]);
250 	dest[R_O3] = SET_LOWER_32(r->r_o3, src[R_O3]);
251 	dest[R_O4] = SET_LOWER_32(r->r_o4, src[R_O4]);
252 	dest[R_O5] = SET_LOWER_32(r->r_o5, src[R_O5]);
253 	dest[R_O6] = SET_LOWER_32(r->r_o6, src[R_O6]);
254 	dest[R_O7] = SET_LOWER_32(r->r_o7, src[R_O7]);
255 
256 	if (lwp->lwp_pcb.pcb_xregstat != XREGNONE) {
257 		struct rwindow *rw = &lwp->lwp_pcb.pcb_xregs;
258 
259 		dest[R_L0] = SET_LOWER_32(rw->rw_local[0], src[R_L0]);
260 		dest[R_L1] = SET_LOWER_32(rw->rw_local[1], src[R_L1]);
261 		dest[R_L2] = SET_LOWER_32(rw->rw_local[2], src[R_L2]);
262 		dest[R_L3] = SET_LOWER_32(rw->rw_local[3], src[R_L3]);
263 		dest[R_L4] = SET_LOWER_32(rw->rw_local[4], src[R_L4]);
264 		dest[R_L5] = SET_LOWER_32(rw->rw_local[5], src[R_L5]);
265 		dest[R_L6] = SET_LOWER_32(rw->rw_local[6], src[R_L6]);
266 		dest[R_L7] = SET_LOWER_32(rw->rw_local[7], src[R_L7]);
267 
268 		dest[R_I0] = SET_LOWER_32(rw->rw_in[0], src[R_I0]);
269 		dest[R_I1] = SET_LOWER_32(rw->rw_in[1], src[R_I1]);
270 		dest[R_I2] = SET_LOWER_32(rw->rw_in[2], src[R_I2]);
271 		dest[R_I3] = SET_LOWER_32(rw->rw_in[3], src[R_I3]);
272 		dest[R_I4] = SET_LOWER_32(rw->rw_in[4], src[R_I4]);
273 		dest[R_I5] = SET_LOWER_32(rw->rw_in[5], src[R_I5]);
274 		dest[R_I6] = SET_LOWER_32(rw->rw_in[6], src[R_I6]);
275 		dest[R_I7] = SET_LOWER_32(rw->rw_in[7], src[R_I7]);
276 	} else {
277 		dest[R_L0] = (uint32_t)src[R_L0];
278 		dest[R_L1] = (uint32_t)src[R_L1];
279 		dest[R_L2] = (uint32_t)src[R_L2];
280 		dest[R_L3] = (uint32_t)src[R_L3];
281 		dest[R_L4] = (uint32_t)src[R_L4];
282 		dest[R_L5] = (uint32_t)src[R_L5];
283 		dest[R_L6] = (uint32_t)src[R_L6];
284 		dest[R_L7] = (uint32_t)src[R_L7];
285 
286 		dest[R_I0] = (uint32_t)src[R_I0];
287 		dest[R_I1] = (uint32_t)src[R_I1];
288 		dest[R_I2] = (uint32_t)src[R_I2];
289 		dest[R_I3] = (uint32_t)src[R_I3];
290 		dest[R_I4] = (uint32_t)src[R_I4];
291 		dest[R_I5] = (uint32_t)src[R_I5];
292 		dest[R_I6] = (uint32_t)src[R_I6];
293 		dest[R_I7] = (uint32_t)src[R_I7];
294 	}
295 
296 	dest[R_CCR] = ((r->r_tstate >> TSTATE_CCR_SHIFT) & CCR_XCC) |
297 	    ((src[R_PSR] >> (TSTATE_CCR_SHIFT-PSR_TSTATE_CC_SHIFT)) & CCR_ICC);
298 
299 	dest[R_PC] = SET_LOWER_32(r->r_pc, src[R_PC]);
300 	dest[R_nPC] = SET_LOWER_32(r->r_npc, src[R_nPC]);
301 	dest[R_Y] = (uint32_t)src[R_Y];
302 
303 	dest[R_ASI] = (r->r_tstate >> TSTATE_ASI_SHIFT) & TSTATE_ASI_MASK;
304 	dest[R_FPRS] = lwptofpu(lwp)->fpu_fprs;
305 }
306 
307 /*
308  * Return 32-bit general registers.
309  */
310 
311 /* conversion from 64-bit register to 32-bit register */
312 #define	R32(r)	(prgreg32_t)(uint32_t)(r)
313 
314 void
315 prgetprregs32(klwp_t *lwp, prgregset32_t prp)
316 {
317 	gregset32_t gr;
318 
319 	extern void getgregs32(klwp_t *, gregset32_t);
320 
321 	ASSERT(MUTEX_NOT_HELD(&lwptoproc(lwp)->p_lock));
322 
323 	getgregs32(lwp, gr);
324 	bzero(prp, sizeof (prp));
325 
326 	/*
327 	 * Can't copy since prgregset_t and gregset_t
328 	 * use different defines.
329 	 */
330 	prp[R_G1] = gr[REG_G1];
331 	prp[R_G2] = gr[REG_G2];
332 	prp[R_G3] = gr[REG_G3];
333 	prp[R_G4] = gr[REG_G4];
334 	prp[R_G5] = gr[REG_G5];
335 	prp[R_G6] = gr[REG_G6];
336 	prp[R_G7] = gr[REG_G7];
337 
338 	prp[R_O0] = gr[REG_O0];
339 	prp[R_O1] = gr[REG_O1];
340 	prp[R_O2] = gr[REG_O2];
341 	prp[R_O3] = gr[REG_O3];
342 	prp[R_O4] = gr[REG_O4];
343 	prp[R_O5] = gr[REG_O5];
344 	prp[R_O6] = gr[REG_O6];
345 	prp[R_O7] = gr[REG_O7];
346 
347 	if (lwp->lwp_pcb.pcb_xregstat != XREGNONE) {
348 		prp[R_L0] = R32(lwp->lwp_pcb.pcb_xregs.rw_local[0]);
349 		prp[R_L1] = R32(lwp->lwp_pcb.pcb_xregs.rw_local[1]);
350 		prp[R_L2] = R32(lwp->lwp_pcb.pcb_xregs.rw_local[2]);
351 		prp[R_L3] = R32(lwp->lwp_pcb.pcb_xregs.rw_local[3]);
352 		prp[R_L4] = R32(lwp->lwp_pcb.pcb_xregs.rw_local[4]);
353 		prp[R_L5] = R32(lwp->lwp_pcb.pcb_xregs.rw_local[5]);
354 		prp[R_L6] = R32(lwp->lwp_pcb.pcb_xregs.rw_local[6]);
355 		prp[R_L7] = R32(lwp->lwp_pcb.pcb_xregs.rw_local[7]);
356 
357 		prp[R_I0] = R32(lwp->lwp_pcb.pcb_xregs.rw_in[0]);
358 		prp[R_I1] = R32(lwp->lwp_pcb.pcb_xregs.rw_in[1]);
359 		prp[R_I2] = R32(lwp->lwp_pcb.pcb_xregs.rw_in[2]);
360 		prp[R_I3] = R32(lwp->lwp_pcb.pcb_xregs.rw_in[3]);
361 		prp[R_I4] = R32(lwp->lwp_pcb.pcb_xregs.rw_in[4]);
362 		prp[R_I5] = R32(lwp->lwp_pcb.pcb_xregs.rw_in[5]);
363 		prp[R_I6] = R32(lwp->lwp_pcb.pcb_xregs.rw_in[6]);
364 		prp[R_I7] = R32(lwp->lwp_pcb.pcb_xregs.rw_in[7]);
365 	}
366 
367 	prp[R_PSR] = gr[REG_PSR];
368 	prp[R_PC]  = gr[REG_PC];
369 	prp[R_nPC] = gr[REG_nPC];
370 	prp[R_Y]   = gr[REG_Y];
371 }
372 
373 #endif	/* _SYSCALL32_IMPL */
374 
375 /*
376  * Get the syscall return values for the lwp.
377  */
378 int
379 prgetrvals(klwp_t *lwp, long *rval1, long *rval2)
380 {
381 	struct regs *r = lwptoregs(lwp);
382 
383 	if (r->r_tstate & TSTATE_IC)
384 		return ((int)r->r_o0);
385 	if (lwp->lwp_eosys == JUSTRETURN) {
386 		*rval1 = 0;
387 		*rval2 = 0;
388 	} else if (lwptoproc(lwp)->p_model == DATAMODEL_ILP32) {
389 		*rval1 = r->r_o0 & (uint32_t)0xffffffffU;
390 		*rval2 = r->r_o1 & (uint32_t)0xffffffffU;
391 	} else {
392 		*rval1 = r->r_o0;
393 		*rval2 = r->r_o1;
394 	}
395 	return (0);
396 }
397 
398 /*
399  * Does the system support floating-point, either through hardware
400  * or by trapping and emulating floating-point machine instructions?
401  */
402 int
403 prhasfp(void)
404 {
405 	/*
406 	 * SunOS5.0 emulates floating-point if FP hardware is not present.
407 	 */
408 	return (1);
409 }
410 
411 /*
412  * Get floating-point registers.
413  */
414 void
415 prgetprfpregs(klwp_t *lwp, prfpregset_t *pfp)
416 {
417 	bzero(pfp, sizeof (*pfp));
418 	/*
419 	 * This works only because prfpregset_t is intentionally
420 	 * constructed to be identical to fpregset_t, with additional
421 	 * space for the floating-point queue at the end.
422 	 */
423 	getfpregs(lwp, (fpregset_t *)pfp);
424 	/*
425 	 * This is supposed to be a pointer to the floating point queue.
426 	 * We can't provide such a thing through the /proc interface.
427 	 */
428 	pfp->pr_filler = NULL;
429 	/*
430 	 * XXX: to be done: fetch the FP queue if it is non-empty.
431 	 */
432 }
433 
434 #ifdef	_SYSCALL32_IMPL
435 void
436 prgetprfpregs32(klwp_t *lwp, prfpregset32_t *pfp)
437 {
438 	bzero(pfp, sizeof (*pfp));
439 	/*
440 	 * This works only because prfpregset32_t is intentionally
441 	 * constructed to be identical to fpregset32_t, with additional
442 	 * space for the floating-point queue at the end.
443 	 */
444 	getfpregs32(lwp, (fpregset32_t *)pfp);
445 	/*
446 	 * This is supposed to be a pointer to the floating point queue.
447 	 * We can't provide such a thing through the /proc interface.
448 	 */
449 	pfp->pr_filler = NULL;
450 	/*
451 	 * XXX: to be done: fetch the FP queue if it is non-empty.
452 	 */
453 }
454 #endif	/* _SYSCALL32_IMPL */
455 
456 /*
457  * Set floating-point registers.
458  */
459 void
460 prsetprfpregs(klwp_t *lwp, prfpregset_t *pfp)
461 {
462 	/*
463 	 * XXX: to be done: store the FP queue if it is non-empty.
464 	 */
465 	pfp->pr_qcnt = 0;
466 	/*
467 	 * We set fpu_en before calling setfpregs() in order to
468 	 * retain the semantics of this operation from older
469 	 * versions of the system.  SunOS 5.4 and prior never
470 	 * queried fpu_en; they just set the registers.  The
471 	 * proper operation if fpu_en is zero is to disable
472 	 * floating point in the target process, but this can
473 	 * only change after a proper end-of-life period for
474 	 * the old semantics.
475 	 */
476 	pfp->pr_en = 1;
477 	/*
478 	 * This works only because prfpregset_t is intentionally
479 	 * constructed to be identical to fpregset_t, with additional
480 	 * space for the floating-point queue at the end.
481 	 */
482 	setfpregs(lwp, (fpregset_t *)pfp);
483 }
484 
485 #ifdef	_SYSCALL32_IMPL
486 void
487 prsetprfpregs32(klwp_t *lwp, prfpregset32_t *pfp)
488 {
489 	/*
490 	 * XXX: to be done: store the FP queue if it is non-empty.
491 	 */
492 	pfp->pr_qcnt = 0;
493 	/*
494 	 * We set fpu_en before calling setfpregs() in order to
495 	 * retain the semantics of this operation from older
496 	 * versions of the system.  SunOS 5.4 and prior never
497 	 * queried fpu_en; they just set the registers.  The
498 	 * proper operation if fpu_en is zero is to disable
499 	 * floating point in the target process, but this can
500 	 * only change after a proper end-of-life period for
501 	 * the old semantics.
502 	 */
503 	pfp->pr_en = 1;
504 	/*
505 	 * This works only because prfpregset32_t is intentionally
506 	 * constructed to be identical to fpregset32_t, with additional
507 	 * space for the floating-point queue at the end.
508 	 */
509 	setfpregs32(lwp, (fpregset32_t *)pfp);
510 }
511 #endif	/* _SYSCALL32_IMPL */
512 
513 /*
514  * Does the system support extra register state?
515  * In a kernel that supports both an _LP64 and an _ILP32 data model,
516  * the answer depends on the data model of the process.
517  * An _LP64 process does not have extra registers.
518  */
519 int
520 prhasx(proc_t *p)
521 {
522 	extern int xregs_exists;
523 
524 	if (p->p_model == DATAMODEL_LP64)
525 		return (0);
526 	else
527 		return (xregs_exists);
528 }
529 
530 /*
531  * Get the size of the extra registers.
532  */
533 int
534 prgetprxregsize(proc_t *p)
535 {
536 	return (xregs_getsize(p));
537 }
538 
539 /*
540  * Get extra registers.
541  */
542 void
543 prgetprxregs(klwp_t *lwp, caddr_t prx)
544 {
545 	extern void xregs_get(struct _klwp *, caddr_t);
546 
547 	(void) xregs_get(lwp, prx);
548 }
549 
550 /*
551  * Set extra registers.
552  */
553 void
554 prsetprxregs(klwp_t *lwp, caddr_t prx)
555 {
556 	extern void xregs_set(struct _klwp *, caddr_t);
557 
558 	(void) xregs_set(lwp, prx);
559 }
560 
561 /*
562  * Get the ancillary state registers.
563  */
564 void
565 prgetasregs(klwp_t *lwp, asrset_t asrset)
566 {
567 	bzero(asrset, sizeof (asrset_t));
568 	getasrs(lwp, asrset);
569 	getfpasrs(lwp, asrset);
570 }
571 
572 /*
573  * Set the ancillary state registers.
574  */
575 void
576 prsetasregs(klwp_t *lwp, asrset_t asrset)
577 {
578 	setasrs(lwp, asrset);
579 	setfpasrs(lwp, asrset);
580 }
581 
582 /*
583  * Return the base (lower limit) of the process stack.
584  */
585 caddr_t
586 prgetstackbase(proc_t *p)
587 {
588 	return (p->p_usrstack - p->p_stksize);
589 }
590 
591 /*
592  * Return the "addr" field for pr_addr in prpsinfo_t.
593  * This is a vestige of the past, so whatever we return is OK.
594  */
595 caddr_t
596 prgetpsaddr(proc_t *p)
597 {
598 	return ((caddr_t)p);
599 }
600 
601 /*
602  * Arrange to single-step the lwp.
603  */
604 void
605 prstep(klwp_t *lwp, int watchstep)
606 {
607 	ASSERT(MUTEX_NOT_HELD(&lwptoproc(lwp)->p_lock));
608 
609 	lwp->lwp_pcb.pcb_step = STEP_REQUESTED;
610 	lwp->lwp_pcb.pcb_tracepc = NULL;
611 	if (watchstep)
612 		lwp->lwp_pcb.pcb_flags |= WATCH_STEP;
613 	else
614 		lwp->lwp_pcb.pcb_flags |= NORMAL_STEP;
615 }
616 
617 /*
618  * Undo prstep().
619  */
620 void
621 prnostep(klwp_t *lwp)
622 {
623 	ASSERT(ttolwp(curthread) == lwp ||
624 	    MUTEX_NOT_HELD(&lwptoproc(lwp)->p_lock));
625 
626 	lwp->lwp_pcb.pcb_step = STEP_NONE;
627 	lwp->lwp_pcb.pcb_tracepc = NULL;
628 	lwp->lwp_pcb.pcb_flags &= ~(NORMAL_STEP|WATCH_STEP);
629 }
630 
631 /*
632  * Return non-zero if a single-step is in effect.
633  */
634 int
635 prisstep(klwp_t *lwp)
636 {
637 	ASSERT(MUTEX_NOT_HELD(&lwptoproc(lwp)->p_lock));
638 
639 	return (lwp->lwp_pcb.pcb_step != STEP_NONE);
640 }
641 
642 /*
643  * Set the PC to the specified virtual address.
644  */
645 void
646 prsvaddr(klwp_t *lwp, caddr_t vaddr)
647 {
648 	struct regs *r = lwptoregs(lwp);
649 
650 	ASSERT(MUTEX_NOT_HELD(&lwptoproc(lwp)->p_lock));
651 
652 	/*
653 	 * pc and npc must be word aligned on sparc.
654 	 * We silently make it so to avoid a watchdog reset.
655 	 */
656 	r->r_pc = (uintptr_t)vaddr & ~03L;
657 	r->r_npc = r->r_pc + 4;
658 }
659 
660 /*
661  * Map address "addr" in address space "as" into a kernel virtual address.
662  * The memory is guaranteed to be resident and locked down.
663  */
664 caddr_t
665 prmapin(struct as *as, caddr_t addr, int writing)
666 {
667 	page_t *pp;
668 	caddr_t kaddr;
669 	pfn_t pfnum;
670 
671 	/*
672 	 * XXX - Because of past mistakes, we have bits being returned
673 	 * by getpfnum that are actually the page type bits of the pte.
674 	 * When the object we are trying to map is a memory page with
675 	 * a page structure everything is ok and we can use the optimal
676 	 * method, ppmapin.  Otherwise, we have to do something special.
677 	 */
678 	pfnum = hat_getpfnum(as->a_hat, addr);
679 	if (pf_is_memory(pfnum)) {
680 		pp = page_numtopp_nolock(pfnum);
681 		if (pp != NULL) {
682 			ASSERT(PAGE_LOCKED(pp));
683 			kaddr = ppmapin(pp, writing ?
684 				(PROT_READ | PROT_WRITE) : PROT_READ,
685 				(caddr_t)-1);
686 			return (kaddr + ((uintptr_t)addr & PAGEOFFSET));
687 		}
688 	}
689 
690 	/*
691 	 * Oh well, we didn't have a page struct for the object we were
692 	 * trying to map in; ppmapin doesn't handle devices, but allocating a
693 	 * heap address allows ppmapout to free virutal space when done.
694 	 */
695 	kaddr = vmem_alloc(heap_arena, PAGESIZE, VM_SLEEP);
696 
697 	hat_devload(kas.a_hat, kaddr, PAGESIZE, pfnum,
698 		writing ? (PROT_READ | PROT_WRITE) : PROT_READ, HAT_LOAD_LOCK);
699 
700 	return (kaddr + ((uintptr_t)addr & PAGEOFFSET));
701 }
702 
703 /*
704  * Unmap address "addr" in address space "as"; inverse of prmapin().
705  */
706 /* ARGSUSED */
707 void
708 prmapout(struct as *as, caddr_t addr, caddr_t vaddr, int writing)
709 {
710 	extern void ppmapout(caddr_t);
711 
712 	vaddr = (caddr_t)((uintptr_t)vaddr & PAGEMASK);
713 	ppmapout(vaddr);
714 }
715 
716 
717 #define	BAMASK22 0xffc00000	/* for masking out disp22 from ba,a */
718 #define	BAA	0x30800000	/* ba,a without disp22 */
719 #define	FBAA	0x31800000	/* fba,a without disp22 */
720 #define	CBAA	0x31c00000	/* cba,a without disp22 */
721 
722 #define	BAMASK19 0xfff80000	/* for masking out disp19 from ba,a %[ix]cc */
723 #define	BAA_icc	0x30480000	/* ba,a %icc without disp19 */
724 #define	BAA_xcc	0x30680000	/* ba,a %xcc without disp19 */
725 
726 
727 /*
728  * Prepare to single-step the lwp if requested.
729  * This is called by the lwp itself just before returning to user level.
730  */
731 void
732 prdostep(void)
733 {
734 	klwp_t *lwp = ttolwp(curthread);
735 	struct regs *r = lwptoregs(lwp);
736 	proc_t *p = lwptoproc(lwp);
737 	struct as *as = p->p_as;
738 	caddr_t pc;
739 	caddr_t npc;
740 
741 	ASSERT(lwp != NULL);
742 	ASSERT(r != NULL);
743 
744 	if (lwp->lwp_pcb.pcb_step == STEP_NONE ||
745 	    lwp->lwp_pcb.pcb_step == STEP_ACTIVE)
746 		return;
747 
748 	if (p->p_model == DATAMODEL_ILP32) {
749 		pc = (caddr_t)(uintptr_t)(caddr32_t)r->r_pc;
750 		npc = (caddr_t)(uintptr_t)(caddr32_t)r->r_npc;
751 	} else {
752 		pc = (caddr_t)r->r_pc;
753 		npc = (caddr_t)r->r_npc;
754 	}
755 
756 	if (lwp->lwp_pcb.pcb_step == STEP_WASACTIVE) {
757 		if (npc == (caddr_t)lwp->lwp_pcb.pcb_tracepc)
758 			r->r_npc = (greg_t)as->a_userlimit;
759 		else {
760 			lwp->lwp_pcb.pcb_tracepc = (void *)pc;
761 			r->r_pc = (greg_t)as->a_userlimit;
762 		}
763 	} else {
764 		/*
765 		 * Single-stepping on sparc is effected by setting nPC
766 		 * to an invalid address and expecting FLTBOUNDS to
767 		 * occur after the instruction at PC is executed.
768 		 * This is not the whole story, however; we must
769 		 * deal with branch-always instructions with the
770 		 * annul bit set as a special case here.
771 		 *
772 		 * fuword() returns -1 on error and we can't distinguish
773 		 * this from a legitimate instruction of all 1's.
774 		 * However 0xffffffff is not one of the branch-always
775 		 * instructions we are interested in.  No problem.
776 		 */
777 		int32_t instr;
778 		int32_t i;
779 
780 		if (fuword32_nowatch((void *)pc, (uint32_t *)&instr) != 0)
781 			instr = -1;
782 		if ((i = instr & BAMASK22) == BAA || i == FBAA || i == CBAA) {
783 			/*
784 			 * For ba,a and relatives, compute the
785 			 * new PC from the instruction.
786 			 */
787 			i = (instr << 10) >> 8;
788 			lwp->lwp_pcb.pcb_tracepc = (void *)(pc + i);
789 			r->r_pc = (greg_t)as->a_userlimit;
790 			r->r_npc = r->r_pc + 4;
791 		} else if ((i = instr & BAMASK19) == BAA_icc || i == BAA_xcc) {
792 			/*
793 			 * For ba,a %icc and ba,a %xcc, compute the
794 			 * new PC from the instruction.
795 			 */
796 			i = (instr << 13) >> 11;
797 			lwp->lwp_pcb.pcb_tracepc = (void *)(pc + i);
798 			r->r_pc = (greg_t)as->a_userlimit;
799 			r->r_npc = r->r_pc + 4;
800 		} else {
801 			lwp->lwp_pcb.pcb_tracepc = (void *)npc;
802 			r->r_npc = (greg_t)as->a_userlimit;
803 		}
804 	}
805 
806 	lwp->lwp_pcb.pcb_step = STEP_ACTIVE;
807 }
808 
809 /*
810  * Wrap up single stepping of the lwp.
811  * This is called by the lwp itself just after it has taken
812  * the FLTBOUNDS trap.  We fix up the PC and nPC to have their
813  * proper values after the step.  We return 1 to indicate that
814  * this fault really is the one we are expecting, else 0.
815  *
816  * This is also called from syscall() and stop() to reset PC
817  * and nPC to their proper values for debugger visibility.
818  */
819 int
820 prundostep(void)
821 {
822 	klwp_t *lwp = ttolwp(curthread);
823 	proc_t *p = ttoproc(curthread);
824 	struct as *as = p->p_as;
825 	int rc = 0;
826 	caddr_t pc;
827 	caddr_t npc;
828 
829 	ASSERT(lwp != NULL);
830 
831 	if (lwp->lwp_pcb.pcb_step == STEP_ACTIVE) {
832 		struct regs *r = lwptoregs(lwp);
833 
834 		ASSERT(r != NULL);
835 
836 		if (p->p_model == DATAMODEL_ILP32) {
837 			pc = (caddr_t)(uintptr_t)(caddr32_t)r->r_pc;
838 			npc = (caddr_t)(uintptr_t)(caddr32_t)r->r_npc;
839 		} else {
840 			pc = (caddr_t)r->r_pc;
841 			npc = (caddr_t)r->r_npc;
842 		}
843 
844 		if (pc == (caddr_t)as->a_userlimit ||
845 		    pc == (caddr_t)as->a_userlimit + 4) {
846 			if (pc == (caddr_t)as->a_userlimit) {
847 				r->r_pc = (greg_t)lwp->lwp_pcb.pcb_tracepc;
848 				if (npc == (caddr_t)as->a_userlimit + 4)
849 					r->r_npc = r->r_pc + 4;
850 			} else {
851 				r->r_pc = (greg_t)lwp->lwp_pcb.pcb_tracepc + 4;
852 				r->r_npc = r->r_pc + 4;
853 			}
854 			rc = 1;
855 		} else {
856 			r->r_npc = (greg_t)lwp->lwp_pcb.pcb_tracepc;
857 		}
858 		lwp->lwp_pcb.pcb_step = STEP_WASACTIVE;
859 	}
860 
861 	return (rc);
862 }
863 
864 /*
865  * Make sure the lwp is in an orderly state
866  * for inspection by a debugger through /proc.
867  * Called from stop() and from syslwp_create().
868  */
869 /* ARGSUSED */
870 void
871 prstop(int why, int what)
872 {
873 	klwp_t *lwp = ttolwp(curthread);
874 	proc_t *p = lwptoproc(lwp);
875 	struct regs *r = lwptoregs(lwp);
876 	kfpu_t *pfp = lwptofpu(lwp);
877 	caddr_t sp;
878 	caddr_t pc;
879 	int watched;
880 	extern void fp_prsave(kfpu_t *);
881 
882 	/*
883 	 * Make sure we don't deadlock on a recursive call
884 	 * to prstop().  stop() tests the lwp_nostop flag.
885 	 */
886 	ASSERT(lwp->lwp_nostop == 0);
887 	lwp->lwp_nostop = 1;
888 	(void) flush_user_windows_to_stack(NULL);
889 	if (lwp->lwp_pcb.pcb_step != STEP_NONE)
890 		(void) prundostep();
891 
892 	if (lwp->lwp_pcb.pcb_xregstat == XREGNONE) {
893 		/*
894 		 * Attempt to fetch the last register window from the stack.
895 		 * If that fails, look for it in the pcb.
896 		 * If that fails, give up.
897 		 */
898 		struct machpcb *mpcb = lwptompcb(lwp);
899 		struct rwindow32 rwindow32;
900 		size_t rw_size;
901 		caddr_t rwp;
902 		int is64;
903 
904 		if (mpcb->mpcb_wstate == WSTATE_USER32) {
905 			rw_size = sizeof (struct rwindow32);
906 			sp = (caddr_t)(uintptr_t)(caddr32_t)r->r_sp;
907 			rwp = sp;
908 			is64 = 0;
909 		} else {
910 			rw_size = sizeof (struct rwindow);
911 			sp = (caddr_t)r->r_sp;
912 			rwp = sp + V9BIAS64;
913 			is64 = 1;
914 		}
915 
916 		watched = watch_disable_addr(rwp, rw_size, S_READ);
917 		if (is64 &&
918 		    copyin(rwp, &lwp->lwp_pcb.pcb_xregs, rw_size) == 0)
919 			lwp->lwp_pcb.pcb_xregstat = XREGPRESENT;
920 		else if (!is64 &&
921 		    copyin(rwp, &rwindow32, rw_size) == 0) {
922 			rwindow_32ton(&rwindow32, &lwp->lwp_pcb.pcb_xregs);
923 			lwp->lwp_pcb.pcb_xregstat = XREGPRESENT;
924 		} else {
925 			int i;
926 
927 			for (i = 0; i < mpcb->mpcb_wbcnt; i++) {
928 				if (sp == mpcb->mpcb_spbuf[i]) {
929 					if (is64) {
930 						bcopy(mpcb->mpcb_wbuf +
931 						    (i * rw_size),
932 						    &lwp->lwp_pcb.pcb_xregs,
933 						    rw_size);
934 					} else {
935 						struct rwindow32 *rw32 =
936 						    (struct rwindow32 *)
937 						    (mpcb->mpcb_wbuf +
938 						    (i * rw_size));
939 						rwindow_32ton(rw32,
940 						    &lwp->lwp_pcb.pcb_xregs);
941 					}
942 					lwp->lwp_pcb.pcb_xregstat = XREGPRESENT;
943 					break;
944 				}
945 			}
946 		}
947 		if (watched)
948 			watch_enable_addr(rwp, rw_size, S_READ);
949 	}
950 
951 	/*
952 	 * Make sure the floating point state is saved.
953 	 */
954 	fp_prsave(pfp);
955 
956 	if (p->p_model == DATAMODEL_ILP32)
957 		pc = (caddr_t)(uintptr_t)(caddr32_t)r->r_pc;
958 	else
959 		pc = (caddr_t)r->r_pc;
960 
961 	if (copyin_nowatch(pc, &lwp->lwp_pcb.pcb_instr,
962 	    sizeof (lwp->lwp_pcb.pcb_instr)) == 0)
963 		lwp->lwp_pcb.pcb_flags |= INSTR_VALID;
964 	else {
965 		lwp->lwp_pcb.pcb_flags &= ~INSTR_VALID;
966 		lwp->lwp_pcb.pcb_instr = 0;
967 	}
968 
969 	(void) save_syscall_args();
970 	ASSERT(lwp->lwp_nostop == 1);
971 	lwp->lwp_nostop = 0;
972 }
973 
974 /*
975  * Fetch the user-level instruction on which the lwp is stopped.
976  * It was saved by the lwp itself, in prstop().
977  * Return non-zero if the instruction is valid.
978  */
979 int
980 prfetchinstr(klwp_t *lwp, ulong_t *ip)
981 {
982 	*ip = (ulong_t)(instr_t)lwp->lwp_pcb.pcb_instr;
983 	return (lwp->lwp_pcb.pcb_flags & INSTR_VALID);
984 }
985 
986 int
987 prnwindows(klwp_t *lwp)
988 {
989 	struct machpcb *mpcb = lwptompcb(lwp);
990 
991 	return (mpcb->mpcb_wbcnt);
992 }
993 
994 void
995 prgetwindows(klwp_t *lwp, gwindows_t *gwp)
996 {
997 	getgwins(lwp, gwp);
998 }
999 
1000 #ifdef	_SYSCALL32_IMPL
1001 void
1002 prgetwindows32(klwp_t *lwp, gwindows32_t *gwp)
1003 {
1004 	getgwins32(lwp, gwp);
1005 }
1006 #endif	/* _SYSCALL32_IMPL */
1007 
1008 /*
1009  * Called from trap() when a load or store instruction
1010  * falls in a watched page but is not a watchpoint.
1011  * We emulate the instruction in the kernel.
1012  */
1013 int
1014 pr_watch_emul(struct regs *rp, caddr_t addr, enum seg_rw rw)
1015 {
1016 	char *badaddr = (caddr_t)(-1);
1017 	int res;
1018 	int watched;
1019 
1020 	/* prevent recursive calls to pr_watch_emul() */
1021 	ASSERT(!(curthread->t_flag & T_WATCHPT));
1022 	curthread->t_flag |= T_WATCHPT;
1023 
1024 	watched = watch_disable_addr(addr, 16, rw);
1025 	res = do_unaligned(rp, &badaddr);
1026 	if (watched)
1027 		watch_enable_addr(addr, 16, rw);
1028 
1029 	curthread->t_flag &= ~T_WATCHPT;
1030 	if (res == SIMU_SUCCESS) {
1031 		rp->r_pc = rp->r_npc;
1032 		rp->r_npc += 4;
1033 		return (1);
1034 	}
1035 	return (0);
1036 }
1037