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