xref: /freebsd/sys/powerpc/powerpc/exec_machdep.c (revision 780fb4a2)
1 /*-
2  * SPDX-License-Identifier: BSD-4-Clause AND BSD-2-Clause-FreeBSD
3  *
4  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
5  * Copyright (C) 1995, 1996 TooLs GmbH.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:
18  *      This product includes software developed by TooLs GmbH.
19  * 4. The name of TooLs GmbH may not be used to endorse or promote products
20  *    derived from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
23  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
28  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 /*-
34  * Copyright (C) 2001 Benno Rice
35  * All rights reserved.
36  *
37  * Redistribution and use in source and binary forms, with or without
38  * modification, are permitted provided that the following conditions
39  * are met:
40  * 1. Redistributions of source code must retain the above copyright
41  *    notice, this list of conditions and the following disclaimer.
42  * 2. Redistributions in binary form must reproduce the above copyright
43  *    notice, this list of conditions and the following disclaimer in the
44  *    documentation and/or other materials provided with the distribution.
45  *
46  * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR
47  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
48  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
49  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
50  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
51  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
52  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
53  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
54  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
55  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
56  *	$NetBSD: machdep.c,v 1.74.2.1 2000/11/01 16:13:48 tv Exp $
57  */
58 
59 #include <sys/cdefs.h>
60 __FBSDID("$FreeBSD$");
61 
62 #include "opt_fpu_emu.h"
63 
64 #include <sys/param.h>
65 #include <sys/proc.h>
66 #include <sys/systm.h>
67 #include <sys/bio.h>
68 #include <sys/buf.h>
69 #include <sys/bus.h>
70 #include <sys/cons.h>
71 #include <sys/cpu.h>
72 #include <sys/exec.h>
73 #include <sys/imgact.h>
74 #include <sys/kernel.h>
75 #include <sys/ktr.h>
76 #include <sys/lock.h>
77 #include <sys/malloc.h>
78 #include <sys/mutex.h>
79 #include <sys/signalvar.h>
80 #include <sys/syscallsubr.h>
81 #include <sys/syscall.h>
82 #include <sys/sysent.h>
83 #include <sys/sysproto.h>
84 #include <sys/ucontext.h>
85 #include <sys/uio.h>
86 
87 #include <machine/altivec.h>
88 #include <machine/cpu.h>
89 #include <machine/elf.h>
90 #include <machine/fpu.h>
91 #include <machine/pcb.h>
92 #include <machine/reg.h>
93 #include <machine/sigframe.h>
94 #include <machine/trap.h>
95 #include <machine/vmparam.h>
96 
97 #ifdef FPU_EMU
98 #include <powerpc/fpu/fpu_extern.h>
99 #endif
100 
101 #ifdef COMPAT_FREEBSD32
102 #include <compat/freebsd32/freebsd32_signal.h>
103 #include <compat/freebsd32/freebsd32_util.h>
104 #include <compat/freebsd32/freebsd32_proto.h>
105 
106 typedef struct __ucontext32 {
107 	sigset_t		uc_sigmask;
108 	mcontext32_t		uc_mcontext;
109 	uint32_t		uc_link;
110 	struct sigaltstack32    uc_stack;
111 	uint32_t		uc_flags;
112 	uint32_t		__spare__[4];
113 } ucontext32_t;
114 
115 struct sigframe32 {
116 	ucontext32_t		sf_uc;
117 	struct siginfo32	sf_si;
118 };
119 
120 static int	grab_mcontext32(struct thread *td, mcontext32_t *, int flags);
121 #endif
122 
123 static int	grab_mcontext(struct thread *, mcontext_t *, int);
124 
125 void
126 sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
127 {
128 	struct trapframe *tf;
129 	struct sigacts *psp;
130 	struct sigframe sf;
131 	struct thread *td;
132 	struct proc *p;
133 	#ifdef COMPAT_FREEBSD32
134 	struct siginfo32 siginfo32;
135 	struct sigframe32 sf32;
136 	#endif
137 	size_t sfpsize;
138 	caddr_t sfp, usfp;
139 	int oonstack, rndfsize;
140 	int sig;
141 	int code;
142 
143 	td = curthread;
144 	p = td->td_proc;
145 	PROC_LOCK_ASSERT(p, MA_OWNED);
146 
147 	psp = p->p_sigacts;
148 	mtx_assert(&psp->ps_mtx, MA_OWNED);
149 	tf = td->td_frame;
150 	oonstack = sigonstack(tf->fixreg[1]);
151 
152 	/*
153 	 * Fill siginfo structure.
154 	 */
155 	ksi->ksi_info.si_signo = ksi->ksi_signo;
156 	ksi->ksi_info.si_addr =
157 	    (void *)((tf->exc == EXC_DSI || tf->exc == EXC_DSE) ?
158 	    tf->dar : tf->srr0);
159 
160 	#ifdef COMPAT_FREEBSD32
161 	if (SV_PROC_FLAG(p, SV_ILP32)) {
162 		siginfo_to_siginfo32(&ksi->ksi_info, &siginfo32);
163 		sig = siginfo32.si_signo;
164 		code = siginfo32.si_code;
165 		sfp = (caddr_t)&sf32;
166 		sfpsize = sizeof(sf32);
167 		rndfsize = roundup(sizeof(sf32), 16);
168 
169 		/*
170 		 * Save user context
171 		 */
172 
173 		memset(&sf32, 0, sizeof(sf32));
174 		grab_mcontext32(td, &sf32.sf_uc.uc_mcontext, 0);
175 
176 		sf32.sf_uc.uc_sigmask = *mask;
177 		sf32.sf_uc.uc_stack.ss_sp = (uintptr_t)td->td_sigstk.ss_sp;
178 		sf32.sf_uc.uc_stack.ss_size = (uint32_t)td->td_sigstk.ss_size;
179 		sf32.sf_uc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK)
180 		    ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE;
181 
182 		sf32.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0;
183 	} else {
184 	#endif
185 		sig = ksi->ksi_signo;
186 		code = ksi->ksi_code;
187 		sfp = (caddr_t)&sf;
188 		sfpsize = sizeof(sf);
189 		#ifdef __powerpc64__
190 		/*
191 		 * 64-bit PPC defines a 288 byte scratch region
192 		 * below the stack.
193 		 */
194 		rndfsize = 288 + roundup(sizeof(sf), 48);
195 		#else
196 		rndfsize = roundup(sizeof(sf), 16);
197 		#endif
198 
199 		/*
200 		 * Save user context
201 		 */
202 
203 		memset(&sf, 0, sizeof(sf));
204 		grab_mcontext(td, &sf.sf_uc.uc_mcontext, 0);
205 
206 		sf.sf_uc.uc_sigmask = *mask;
207 		sf.sf_uc.uc_stack = td->td_sigstk;
208 		sf.sf_uc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK)
209 		    ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE;
210 
211 		sf.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0;
212 	#ifdef COMPAT_FREEBSD32
213 	}
214 	#endif
215 
216 	CTR4(KTR_SIG, "sendsig: td=%p (%s) catcher=%p sig=%d", td, p->p_comm,
217 	     catcher, sig);
218 
219 	/*
220 	 * Allocate and validate space for the signal handler context.
221 	 */
222 	if ((td->td_pflags & TDP_ALTSTACK) != 0 && !oonstack &&
223 	    SIGISMEMBER(psp->ps_sigonstack, sig)) {
224 		usfp = (void *)(((uintptr_t)td->td_sigstk.ss_sp +
225 		   td->td_sigstk.ss_size - rndfsize) & ~0xFul);
226 	} else {
227 		usfp = (void *)((tf->fixreg[1] - rndfsize) & ~0xFul);
228 	}
229 
230 	/*
231 	 * Save the floating-point state, if necessary, then copy it.
232 	 */
233 	/* XXX */
234 
235 	/*
236 	 * Set up the registers to return to sigcode.
237 	 *
238 	 *   r1/sp - sigframe ptr
239 	 *   lr    - sig function, dispatched to by blrl in trampoline
240 	 *   r3    - sig number
241 	 *   r4    - SIGINFO ? &siginfo : exception code
242 	 *   r5    - user context
243 	 *   srr0  - trampoline function addr
244 	 */
245 	tf->lr = (register_t)catcher;
246 	tf->fixreg[1] = (register_t)usfp;
247 	tf->fixreg[FIRSTARG] = sig;
248 	#ifdef COMPAT_FREEBSD32
249 	tf->fixreg[FIRSTARG+2] = (register_t)usfp +
250 	    ((SV_PROC_FLAG(p, SV_ILP32)) ?
251 	    offsetof(struct sigframe32, sf_uc) :
252 	    offsetof(struct sigframe, sf_uc));
253 	#else
254 	tf->fixreg[FIRSTARG+2] = (register_t)usfp +
255 	    offsetof(struct sigframe, sf_uc);
256 	#endif
257 	if (SIGISMEMBER(psp->ps_siginfo, sig)) {
258 		/*
259 		 * Signal handler installed with SA_SIGINFO.
260 		 */
261 		#ifdef COMPAT_FREEBSD32
262 		if (SV_PROC_FLAG(p, SV_ILP32)) {
263 			sf32.sf_si = siginfo32;
264 			tf->fixreg[FIRSTARG+1] = (register_t)usfp +
265 			    offsetof(struct sigframe32, sf_si);
266 			sf32.sf_si = siginfo32;
267 		} else  {
268 		#endif
269 			tf->fixreg[FIRSTARG+1] = (register_t)usfp +
270 			    offsetof(struct sigframe, sf_si);
271 			sf.sf_si = ksi->ksi_info;
272 		#ifdef COMPAT_FREEBSD32
273 		}
274 		#endif
275 	} else {
276 		/* Old FreeBSD-style arguments. */
277 		tf->fixreg[FIRSTARG+1] = code;
278 		tf->fixreg[FIRSTARG+3] = (tf->exc == EXC_DSI) ?
279 		    tf->dar : tf->srr0;
280 	}
281 	mtx_unlock(&psp->ps_mtx);
282 	PROC_UNLOCK(p);
283 
284 	tf->srr0 = (register_t)p->p_sysent->sv_sigcode_base;
285 
286 	/*
287 	 * copy the frame out to userland.
288 	 */
289 	if (copyout(sfp, usfp, sfpsize) != 0) {
290 		/*
291 		 * Process has trashed its stack. Kill it.
292 		 */
293 		CTR2(KTR_SIG, "sendsig: sigexit td=%p sfp=%p", td, sfp);
294 		PROC_LOCK(p);
295 		sigexit(td, SIGILL);
296 	}
297 
298 	CTR3(KTR_SIG, "sendsig: return td=%p pc=%#x sp=%#x", td,
299 	     tf->srr0, tf->fixreg[1]);
300 
301 	PROC_LOCK(p);
302 	mtx_lock(&psp->ps_mtx);
303 }
304 
305 int
306 sys_sigreturn(struct thread *td, struct sigreturn_args *uap)
307 {
308 	ucontext_t uc;
309 	int error;
310 
311 	CTR2(KTR_SIG, "sigreturn: td=%p ucp=%p", td, uap->sigcntxp);
312 
313 	if (copyin(uap->sigcntxp, &uc, sizeof(uc)) != 0) {
314 		CTR1(KTR_SIG, "sigreturn: efault td=%p", td);
315 		return (EFAULT);
316 	}
317 
318 	error = set_mcontext(td, &uc.uc_mcontext);
319 	if (error != 0)
320 		return (error);
321 
322 	kern_sigprocmask(td, SIG_SETMASK, &uc.uc_sigmask, NULL, 0);
323 
324 	CTR3(KTR_SIG, "sigreturn: return td=%p pc=%#x sp=%#x",
325 	     td, uc.uc_mcontext.mc_srr0, uc.uc_mcontext.mc_gpr[1]);
326 
327 	return (EJUSTRETURN);
328 }
329 
330 #ifdef COMPAT_FREEBSD4
331 int
332 freebsd4_sigreturn(struct thread *td, struct freebsd4_sigreturn_args *uap)
333 {
334 
335 	return sys_sigreturn(td, (struct sigreturn_args *)uap);
336 }
337 #endif
338 
339 /*
340  * Construct a PCB from a trapframe. This is called from kdb_trap() where
341  * we want to start a backtrace from the function that caused us to enter
342  * the debugger. We have the context in the trapframe, but base the trace
343  * on the PCB. The PCB doesn't have to be perfect, as long as it contains
344  * enough for a backtrace.
345  */
346 void
347 makectx(struct trapframe *tf, struct pcb *pcb)
348 {
349 
350 	pcb->pcb_lr = tf->srr0;
351 	pcb->pcb_sp = tf->fixreg[1];
352 }
353 
354 /*
355  * get_mcontext/sendsig helper routine that doesn't touch the
356  * proc lock
357  */
358 static int
359 grab_mcontext(struct thread *td, mcontext_t *mcp, int flags)
360 {
361 	struct pcb *pcb;
362 	int i;
363 
364 	pcb = td->td_pcb;
365 
366 	memset(mcp, 0, sizeof(mcontext_t));
367 
368 	mcp->mc_vers = _MC_VERSION;
369 	mcp->mc_flags = 0;
370 	memcpy(&mcp->mc_frame, td->td_frame, sizeof(struct trapframe));
371 	if (flags & GET_MC_CLEAR_RET) {
372 		mcp->mc_gpr[3] = 0;
373 		mcp->mc_gpr[4] = 0;
374 	}
375 
376 	/*
377 	 * This assumes that floating-point context is *not* lazy,
378 	 * so if the thread has used FP there would have been a
379 	 * FP-unavailable exception that would have set things up
380 	 * correctly.
381 	 */
382 	if (pcb->pcb_flags & PCB_FPREGS) {
383 		if (pcb->pcb_flags & PCB_FPU) {
384 			KASSERT(td == curthread,
385 				("get_mcontext: fp save not curthread"));
386 			critical_enter();
387 			save_fpu(td);
388 			critical_exit();
389 		}
390 		mcp->mc_flags |= _MC_FP_VALID;
391 		memcpy(&mcp->mc_fpscr, &pcb->pcb_fpu.fpscr, sizeof(double));
392 		for (i = 0; i < 32; i++)
393 			memcpy(&mcp->mc_fpreg[i], &pcb->pcb_fpu.fpr[i].fpr,
394 			    sizeof(double));
395 	}
396 
397 	if (pcb->pcb_flags & PCB_VSX) {
398 		for (i = 0; i < 32; i++)
399 			memcpy(&mcp->mc_vsxfpreg[i],
400 			    &pcb->pcb_fpu.fpr[i].vsr[2], sizeof(double));
401 	}
402 
403 	/*
404 	 * Repeat for Altivec context
405 	 */
406 
407 	if (pcb->pcb_flags & PCB_VEC) {
408 		KASSERT(td == curthread,
409 			("get_mcontext: fp save not curthread"));
410 		critical_enter();
411 		save_vec(td);
412 		critical_exit();
413 		mcp->mc_flags |= _MC_AV_VALID;
414 		mcp->mc_vscr  = pcb->pcb_vec.vscr;
415 		mcp->mc_vrsave =  pcb->pcb_vec.vrsave;
416 		memcpy(mcp->mc_avec, pcb->pcb_vec.vr, sizeof(mcp->mc_avec));
417 	}
418 
419 	mcp->mc_len = sizeof(*mcp);
420 
421 	return (0);
422 }
423 
424 int
425 get_mcontext(struct thread *td, mcontext_t *mcp, int flags)
426 {
427 	int error;
428 
429 	error = grab_mcontext(td, mcp, flags);
430 	if (error == 0) {
431 		PROC_LOCK(curthread->td_proc);
432 		mcp->mc_onstack = sigonstack(td->td_frame->fixreg[1]);
433 		PROC_UNLOCK(curthread->td_proc);
434 	}
435 
436 	return (error);
437 }
438 
439 int
440 set_mcontext(struct thread *td, mcontext_t *mcp)
441 {
442 	struct pcb *pcb;
443 	struct trapframe *tf;
444 	register_t tls;
445 	int i;
446 
447 	pcb = td->td_pcb;
448 	tf = td->td_frame;
449 
450 	if (mcp->mc_vers != _MC_VERSION || mcp->mc_len != sizeof(*mcp))
451 		return (EINVAL);
452 
453 	/*
454 	 * Don't let the user set privileged MSR bits
455 	 */
456 	if ((mcp->mc_srr1 & psl_userstatic) != (tf->srr1 & psl_userstatic)) {
457 		return (EINVAL);
458 	}
459 
460 	/* Copy trapframe, preserving TLS pointer across context change */
461 	if (SV_PROC_FLAG(td->td_proc, SV_LP64))
462 		tls = tf->fixreg[13];
463 	else
464 		tls = tf->fixreg[2];
465 	memcpy(tf, mcp->mc_frame, sizeof(mcp->mc_frame));
466 	if (SV_PROC_FLAG(td->td_proc, SV_LP64))
467 		tf->fixreg[13] = tls;
468 	else
469 		tf->fixreg[2] = tls;
470 
471 	if (mcp->mc_flags & _MC_FP_VALID) {
472 		/* enable_fpu() will happen lazily on a fault */
473 		pcb->pcb_flags |= PCB_FPREGS;
474 		memcpy(&pcb->pcb_fpu.fpscr, &mcp->mc_fpscr, sizeof(double));
475 		bzero(pcb->pcb_fpu.fpr, sizeof(pcb->pcb_fpu.fpr));
476 		for (i = 0; i < 32; i++) {
477 			memcpy(&pcb->pcb_fpu.fpr[i].fpr, &mcp->mc_fpreg[i],
478 			    sizeof(double));
479 			memcpy(&pcb->pcb_fpu.fpr[i].vsr[2],
480 			    &mcp->mc_vsxfpreg[i], sizeof(double));
481 		}
482 	}
483 
484 	if (mcp->mc_flags & _MC_AV_VALID) {
485 		if ((pcb->pcb_flags & PCB_VEC) != PCB_VEC) {
486 			critical_enter();
487 			enable_vec(td);
488 			critical_exit();
489 		}
490 		pcb->pcb_vec.vscr = mcp->mc_vscr;
491 		pcb->pcb_vec.vrsave = mcp->mc_vrsave;
492 		memcpy(pcb->pcb_vec.vr, mcp->mc_avec, sizeof(mcp->mc_avec));
493 	}
494 
495 	return (0);
496 }
497 
498 /*
499  * Set set up registers on exec.
500  */
501 void
502 exec_setregs(struct thread *td, struct image_params *imgp, u_long stack)
503 {
504 	struct trapframe	*tf;
505 	register_t		argc;
506 
507 	tf = trapframe(td);
508 	bzero(tf, sizeof *tf);
509 	#ifdef __powerpc64__
510 	tf->fixreg[1] = -roundup(-stack + 48, 16);
511 	#else
512 	tf->fixreg[1] = -roundup(-stack + 8, 16);
513 	#endif
514 
515 	/*
516 	 * Set up arguments for _start():
517 	 *	_start(argc, argv, envp, obj, cleanup, ps_strings);
518 	 *
519 	 * Notes:
520 	 *	- obj and cleanup are the auxilliary and termination
521 	 *	  vectors.  They are fixed up by ld.elf_so.
522 	 *	- ps_strings is a NetBSD extention, and will be
523 	 * 	  ignored by executables which are strictly
524 	 *	  compliant with the SVR4 ABI.
525 	 */
526 
527 	/* Collect argc from the user stack */
528 	argc = fuword((void *)stack);
529 
530 	tf->fixreg[3] = argc;
531 	tf->fixreg[4] = stack + sizeof(register_t);
532 	tf->fixreg[5] = stack + (2 + argc)*sizeof(register_t);
533 	tf->fixreg[6] = 0;				/* auxillary vector */
534 	tf->fixreg[7] = 0;				/* termination vector */
535 	tf->fixreg[8] = (register_t)imgp->ps_strings;	/* NetBSD extension */
536 
537 	tf->srr0 = imgp->entry_addr;
538 	#ifdef __powerpc64__
539 	tf->fixreg[12] = imgp->entry_addr;
540 	#endif
541 	tf->srr1 = psl_userset | PSL_FE_DFLT;
542 	td->td_pcb->pcb_flags = 0;
543 }
544 
545 #ifdef COMPAT_FREEBSD32
546 void
547 ppc32_setregs(struct thread *td, struct image_params *imgp, u_long stack)
548 {
549 	struct trapframe	*tf;
550 	uint32_t		argc;
551 
552 	tf = trapframe(td);
553 	bzero(tf, sizeof *tf);
554 	tf->fixreg[1] = -roundup(-stack + 8, 16);
555 
556 	argc = fuword32((void *)stack);
557 
558 	tf->fixreg[3] = argc;
559 	tf->fixreg[4] = stack + sizeof(uint32_t);
560 	tf->fixreg[5] = stack + (2 + argc)*sizeof(uint32_t);
561 	tf->fixreg[6] = 0;				/* auxillary vector */
562 	tf->fixreg[7] = 0;				/* termination vector */
563 	tf->fixreg[8] = (register_t)imgp->ps_strings;	/* NetBSD extension */
564 
565 	tf->srr0 = imgp->entry_addr;
566 	tf->srr1 = psl_userset32 | PSL_FE_DFLT;
567 	td->td_pcb->pcb_flags = 0;
568 }
569 #endif
570 
571 int
572 fill_regs(struct thread *td, struct reg *regs)
573 {
574 	struct trapframe *tf;
575 
576 	tf = td->td_frame;
577 	memcpy(regs, tf, sizeof(struct reg));
578 
579 	return (0);
580 }
581 
582 int
583 fill_dbregs(struct thread *td, struct dbreg *dbregs)
584 {
585 	/* No debug registers on PowerPC */
586 	return (ENOSYS);
587 }
588 
589 int
590 fill_fpregs(struct thread *td, struct fpreg *fpregs)
591 {
592 	struct pcb *pcb;
593 	int i;
594 
595 	pcb = td->td_pcb;
596 
597 	if ((pcb->pcb_flags & PCB_FPREGS) == 0)
598 		memset(fpregs, 0, sizeof(struct fpreg));
599 	else {
600 		memcpy(&fpregs->fpscr, &pcb->pcb_fpu.fpscr, sizeof(double));
601 		for (i = 0; i < 32; i++)
602 			memcpy(&fpregs->fpreg[i], &pcb->pcb_fpu.fpr[i].fpr,
603 			    sizeof(double));
604 	}
605 
606 	return (0);
607 }
608 
609 int
610 set_regs(struct thread *td, struct reg *regs)
611 {
612 	struct trapframe *tf;
613 
614 	tf = td->td_frame;
615 	memcpy(tf, regs, sizeof(struct reg));
616 
617 	return (0);
618 }
619 
620 int
621 set_dbregs(struct thread *td, struct dbreg *dbregs)
622 {
623 	/* No debug registers on PowerPC */
624 	return (ENOSYS);
625 }
626 
627 int
628 set_fpregs(struct thread *td, struct fpreg *fpregs)
629 {
630 	struct pcb *pcb;
631 	int i;
632 
633 	pcb = td->td_pcb;
634 	pcb->pcb_flags |= PCB_FPREGS;
635 	memcpy(&pcb->pcb_fpu.fpscr, &fpregs->fpscr, sizeof(double));
636 	for (i = 0; i < 32; i++) {
637 		memcpy(&pcb->pcb_fpu.fpr[i].fpr, &fpregs->fpreg[i],
638 		    sizeof(double));
639 	}
640 
641 	return (0);
642 }
643 
644 #ifdef COMPAT_FREEBSD32
645 int
646 set_regs32(struct thread *td, struct reg32 *regs)
647 {
648 	struct trapframe *tf;
649 	int i;
650 
651 	tf = td->td_frame;
652 	for (i = 0; i < 32; i++)
653 		tf->fixreg[i] = regs->fixreg[i];
654 	tf->lr = regs->lr;
655 	tf->cr = regs->cr;
656 	tf->xer = regs->xer;
657 	tf->ctr = regs->ctr;
658 	tf->srr0 = regs->pc;
659 
660 	return (0);
661 }
662 
663 int
664 fill_regs32(struct thread *td, struct reg32 *regs)
665 {
666 	struct trapframe *tf;
667 	int i;
668 
669 	tf = td->td_frame;
670 	for (i = 0; i < 32; i++)
671 		regs->fixreg[i] = tf->fixreg[i];
672 	regs->lr = tf->lr;
673 	regs->cr = tf->cr;
674 	regs->xer = tf->xer;
675 	regs->ctr = tf->ctr;
676 	regs->pc = tf->srr0;
677 
678 	return (0);
679 }
680 
681 static int
682 grab_mcontext32(struct thread *td, mcontext32_t *mcp, int flags)
683 {
684 	mcontext_t mcp64;
685 	int i, error;
686 
687 	error = grab_mcontext(td, &mcp64, flags);
688 	if (error != 0)
689 		return (error);
690 
691 	mcp->mc_vers = mcp64.mc_vers;
692 	mcp->mc_flags = mcp64.mc_flags;
693 	mcp->mc_onstack = mcp64.mc_onstack;
694 	mcp->mc_len = mcp64.mc_len;
695 	memcpy(mcp->mc_avec,mcp64.mc_avec,sizeof(mcp64.mc_avec));
696 	memcpy(mcp->mc_av,mcp64.mc_av,sizeof(mcp64.mc_av));
697 	for (i = 0; i < 42; i++)
698 		mcp->mc_frame[i] = mcp64.mc_frame[i];
699 	memcpy(mcp->mc_fpreg,mcp64.mc_fpreg,sizeof(mcp64.mc_fpreg));
700 	memcpy(mcp->mc_vsxfpreg,mcp64.mc_vsxfpreg,sizeof(mcp64.mc_vsxfpreg));
701 
702 	return (0);
703 }
704 
705 static int
706 get_mcontext32(struct thread *td, mcontext32_t *mcp, int flags)
707 {
708 	int error;
709 
710 	error = grab_mcontext32(td, mcp, flags);
711 	if (error == 0) {
712 		PROC_LOCK(curthread->td_proc);
713 		mcp->mc_onstack = sigonstack(td->td_frame->fixreg[1]);
714 		PROC_UNLOCK(curthread->td_proc);
715 	}
716 
717 	return (error);
718 }
719 
720 static int
721 set_mcontext32(struct thread *td, mcontext32_t *mcp)
722 {
723 	mcontext_t mcp64;
724 	int i, error;
725 
726 	mcp64.mc_vers = mcp->mc_vers;
727 	mcp64.mc_flags = mcp->mc_flags;
728 	mcp64.mc_onstack = mcp->mc_onstack;
729 	mcp64.mc_len = mcp->mc_len;
730 	memcpy(mcp64.mc_avec,mcp->mc_avec,sizeof(mcp64.mc_avec));
731 	memcpy(mcp64.mc_av,mcp->mc_av,sizeof(mcp64.mc_av));
732 	for (i = 0; i < 42; i++)
733 		mcp64.mc_frame[i] = mcp->mc_frame[i];
734 	mcp64.mc_srr1 |= (td->td_frame->srr1 & 0xFFFFFFFF00000000ULL);
735 	memcpy(mcp64.mc_fpreg,mcp->mc_fpreg,sizeof(mcp64.mc_fpreg));
736 	memcpy(mcp64.mc_vsxfpreg,mcp->mc_vsxfpreg,sizeof(mcp64.mc_vsxfpreg));
737 
738 	error = set_mcontext(td, &mcp64);
739 
740 	return (error);
741 }
742 #endif
743 
744 #ifdef COMPAT_FREEBSD32
745 int
746 freebsd32_sigreturn(struct thread *td, struct freebsd32_sigreturn_args *uap)
747 {
748 	ucontext32_t uc;
749 	int error;
750 
751 	CTR2(KTR_SIG, "sigreturn: td=%p ucp=%p", td, uap->sigcntxp);
752 
753 	if (copyin(uap->sigcntxp, &uc, sizeof(uc)) != 0) {
754 		CTR1(KTR_SIG, "sigreturn: efault td=%p", td);
755 		return (EFAULT);
756 	}
757 
758 	error = set_mcontext32(td, &uc.uc_mcontext);
759 	if (error != 0)
760 		return (error);
761 
762 	kern_sigprocmask(td, SIG_SETMASK, &uc.uc_sigmask, NULL, 0);
763 
764 	CTR3(KTR_SIG, "sigreturn: return td=%p pc=%#x sp=%#x",
765 	     td, uc.uc_mcontext.mc_srr0, uc.uc_mcontext.mc_gpr[1]);
766 
767 	return (EJUSTRETURN);
768 }
769 
770 /*
771  * The first two fields of a ucontext_t are the signal mask and the machine
772  * context.  The next field is uc_link; we want to avoid destroying the link
773  * when copying out contexts.
774  */
775 #define	UC32_COPY_SIZE	offsetof(ucontext32_t, uc_link)
776 
777 int
778 freebsd32_getcontext(struct thread *td, struct freebsd32_getcontext_args *uap)
779 {
780 	ucontext32_t uc;
781 	int ret;
782 
783 	if (uap->ucp == NULL)
784 		ret = EINVAL;
785 	else {
786 		get_mcontext32(td, &uc.uc_mcontext, GET_MC_CLEAR_RET);
787 		PROC_LOCK(td->td_proc);
788 		uc.uc_sigmask = td->td_sigmask;
789 		PROC_UNLOCK(td->td_proc);
790 		ret = copyout(&uc, uap->ucp, UC32_COPY_SIZE);
791 	}
792 	return (ret);
793 }
794 
795 int
796 freebsd32_setcontext(struct thread *td, struct freebsd32_setcontext_args *uap)
797 {
798 	ucontext32_t uc;
799 	int ret;
800 
801 	if (uap->ucp == NULL)
802 		ret = EINVAL;
803 	else {
804 		ret = copyin(uap->ucp, &uc, UC32_COPY_SIZE);
805 		if (ret == 0) {
806 			ret = set_mcontext32(td, &uc.uc_mcontext);
807 			if (ret == 0) {
808 				kern_sigprocmask(td, SIG_SETMASK,
809 				    &uc.uc_sigmask, NULL, 0);
810 			}
811 		}
812 	}
813 	return (ret == 0 ? EJUSTRETURN : ret);
814 }
815 
816 int
817 freebsd32_swapcontext(struct thread *td, struct freebsd32_swapcontext_args *uap)
818 {
819 	ucontext32_t uc;
820 	int ret;
821 
822 	if (uap->oucp == NULL || uap->ucp == NULL)
823 		ret = EINVAL;
824 	else {
825 		get_mcontext32(td, &uc.uc_mcontext, GET_MC_CLEAR_RET);
826 		PROC_LOCK(td->td_proc);
827 		uc.uc_sigmask = td->td_sigmask;
828 		PROC_UNLOCK(td->td_proc);
829 		ret = copyout(&uc, uap->oucp, UC32_COPY_SIZE);
830 		if (ret == 0) {
831 			ret = copyin(uap->ucp, &uc, UC32_COPY_SIZE);
832 			if (ret == 0) {
833 				ret = set_mcontext32(td, &uc.uc_mcontext);
834 				if (ret == 0) {
835 					kern_sigprocmask(td, SIG_SETMASK,
836 					    &uc.uc_sigmask, NULL, 0);
837 				}
838 			}
839 		}
840 	}
841 	return (ret == 0 ? EJUSTRETURN : ret);
842 }
843 
844 #endif
845 
846 void
847 cpu_set_syscall_retval(struct thread *td, int error)
848 {
849 	struct proc *p;
850 	struct trapframe *tf;
851 	int fixup;
852 
853 	if (error == EJUSTRETURN)
854 		return;
855 
856 	p = td->td_proc;
857 	tf = td->td_frame;
858 
859 	if (tf->fixreg[0] == SYS___syscall &&
860 	    (SV_PROC_FLAG(p, SV_ILP32))) {
861 		int code = tf->fixreg[FIRSTARG + 1];
862 		if (p->p_sysent->sv_mask)
863 			code &= p->p_sysent->sv_mask;
864 		fixup = (
865 #if defined(COMPAT_FREEBSD6) && defined(SYS_freebsd6_lseek)
866 		    code != SYS_freebsd6_lseek &&
867 #endif
868 		    code != SYS_lseek) ?  1 : 0;
869 	} else
870 		fixup = 0;
871 
872 	switch (error) {
873 	case 0:
874 		if (fixup) {
875 			/*
876 			 * 64-bit return, 32-bit syscall. Fixup byte order
877 			 */
878 			tf->fixreg[FIRSTARG] = 0;
879 			tf->fixreg[FIRSTARG + 1] = td->td_retval[0];
880 		} else {
881 			tf->fixreg[FIRSTARG] = td->td_retval[0];
882 			tf->fixreg[FIRSTARG + 1] = td->td_retval[1];
883 		}
884 		tf->cr &= ~0x10000000;		/* Unset summary overflow */
885 		break;
886 	case ERESTART:
887 		/*
888 		 * Set user's pc back to redo the system call.
889 		 */
890 		tf->srr0 -= 4;
891 		break;
892 	default:
893 		tf->fixreg[FIRSTARG] = SV_ABI_ERRNO(p, error);
894 		tf->cr |= 0x10000000;		/* Set summary overflow */
895 		break;
896 	}
897 }
898 
899 /*
900  * Threading functions
901  */
902 void
903 cpu_thread_exit(struct thread *td)
904 {
905 }
906 
907 void
908 cpu_thread_clean(struct thread *td)
909 {
910 }
911 
912 void
913 cpu_thread_alloc(struct thread *td)
914 {
915 	struct pcb *pcb;
916 
917 	pcb = (struct pcb *)((td->td_kstack + td->td_kstack_pages * PAGE_SIZE -
918 	    sizeof(struct pcb)) & ~0x2fUL);
919 	td->td_pcb = pcb;
920 	td->td_frame = (struct trapframe *)pcb - 1;
921 }
922 
923 void
924 cpu_thread_free(struct thread *td)
925 {
926 }
927 
928 int
929 cpu_set_user_tls(struct thread *td, void *tls_base)
930 {
931 
932 	if (SV_PROC_FLAG(td->td_proc, SV_LP64))
933 		td->td_frame->fixreg[13] = (register_t)tls_base + 0x7010;
934 	else
935 		td->td_frame->fixreg[2] = (register_t)tls_base + 0x7008;
936 	return (0);
937 }
938 
939 void
940 cpu_copy_thread(struct thread *td, struct thread *td0)
941 {
942 	struct pcb *pcb2;
943 	struct trapframe *tf;
944 	struct callframe *cf;
945 
946 	pcb2 = td->td_pcb;
947 
948 	/* Copy the upcall pcb */
949 	bcopy(td0->td_pcb, pcb2, sizeof(*pcb2));
950 
951 	/* Create a stack for the new thread */
952 	tf = td->td_frame;
953 	bcopy(td0->td_frame, tf, sizeof(struct trapframe));
954 	tf->fixreg[FIRSTARG] = 0;
955 	tf->fixreg[FIRSTARG + 1] = 0;
956 	tf->cr &= ~0x10000000;
957 
958 	/* Set registers for trampoline to user mode. */
959 	cf = (struct callframe *)tf - 1;
960 	memset(cf, 0, sizeof(struct callframe));
961 	cf->cf_func = (register_t)fork_return;
962 	cf->cf_arg0 = (register_t)td;
963 	cf->cf_arg1 = (register_t)tf;
964 
965 	pcb2->pcb_sp = (register_t)cf;
966 	#if defined(__powerpc64__) && (!defined(_CALL_ELF) || _CALL_ELF == 1)
967 	pcb2->pcb_lr = ((register_t *)fork_trampoline)[0];
968 	pcb2->pcb_toc = ((register_t *)fork_trampoline)[1];
969 	#else
970 	pcb2->pcb_lr = (register_t)fork_trampoline;
971 	pcb2->pcb_context[0] = pcb2->pcb_lr;
972 	#endif
973 	pcb2->pcb_cpu.aim.usr_vsid = 0;
974 
975 	/* Setup to release spin count in fork_exit(). */
976 	td->td_md.md_spinlock_count = 1;
977 	td->td_md.md_saved_msr = psl_kernset;
978 }
979 
980 void
981 cpu_set_upcall(struct thread *td, void (*entry)(void *), void *arg,
982     stack_t *stack)
983 {
984 	struct trapframe *tf;
985 	uintptr_t sp;
986 
987 	tf = td->td_frame;
988 	/* align stack and alloc space for frame ptr and saved LR */
989 	#ifdef __powerpc64__
990 	sp = ((uintptr_t)stack->ss_sp + stack->ss_size - 48) &
991 	    ~0x1f;
992 	#else
993 	sp = ((uintptr_t)stack->ss_sp + stack->ss_size - 8) &
994 	    ~0x1f;
995 	#endif
996 	bzero(tf, sizeof(struct trapframe));
997 
998 	tf->fixreg[1] = (register_t)sp;
999 	tf->fixreg[3] = (register_t)arg;
1000 	if (SV_PROC_FLAG(td->td_proc, SV_ILP32)) {
1001 		tf->srr0 = (register_t)entry;
1002 		#ifdef __powerpc64__
1003 		tf->srr1 = psl_userset32 | PSL_FE_DFLT;
1004 		#else
1005 		tf->srr1 = psl_userset | PSL_FE_DFLT;
1006 		#endif
1007 	} else {
1008 	    #ifdef __powerpc64__
1009 		register_t entry_desc[3];
1010 		(void)copyin((void *)entry, entry_desc, sizeof(entry_desc));
1011 		tf->srr0 = entry_desc[0];
1012 		tf->fixreg[2] = entry_desc[1];
1013 		tf->fixreg[11] = entry_desc[2];
1014 		tf->srr1 = psl_userset | PSL_FE_DFLT;
1015 	    #endif
1016 	}
1017 
1018 	td->td_pcb->pcb_flags = 0;
1019 
1020 	td->td_retval[0] = (register_t)entry;
1021 	td->td_retval[1] = 0;
1022 }
1023 
1024 static int
1025 emulate_mfspr(int spr, int reg, struct trapframe *frame){
1026 	struct thread *td;
1027 
1028 	td = curthread;
1029 
1030 	if (spr == SPR_DSCR) {
1031 		// If DSCR was never set, get the default DSCR
1032 		if ((td->td_pcb->pcb_flags & PCB_CDSCR) == 0)
1033 			td->td_pcb->pcb_dscr = mfspr(SPR_DSCR);
1034 
1035 		frame->fixreg[reg] = td->td_pcb->pcb_dscr;
1036 		frame->srr0 += 4;
1037 		return 0;
1038 	} else
1039 		return SIGILL;
1040 }
1041 
1042 static int
1043 emulate_mtspr(int spr, int reg, struct trapframe *frame){
1044 	struct thread *td;
1045 
1046 	td = curthread;
1047 
1048 	if (spr == SPR_DSCR) {
1049 		td->td_pcb->pcb_flags |= PCB_CDSCR;
1050 		td->td_pcb->pcb_dscr = frame->fixreg[reg];
1051 		frame->srr0 += 4;
1052 		return 0;
1053 	} else
1054 		return SIGILL;
1055 }
1056 
1057 #define XFX 0xFC0007FF
1058 int
1059 ppc_instr_emulate(struct trapframe *frame, struct pcb *pcb)
1060 {
1061 	uint32_t instr;
1062 	int reg, sig;
1063 	int rs, spr;
1064 
1065 	instr = fuword32((void *)frame->srr0);
1066 	sig = SIGILL;
1067 
1068 	if ((instr & 0xfc1fffff) == 0x7c1f42a6) {	/* mfpvr */
1069 		reg = (instr & ~0xfc1fffff) >> 21;
1070 		frame->fixreg[reg] = mfpvr();
1071 		frame->srr0 += 4;
1072 		return (0);
1073 	} else if ((instr & XFX) == 0x7c0002a6) {	/* mfspr */
1074 		rs = (instr &  0x3e00000) >> 21;
1075 		spr = (instr & 0x1ff800) >> 16;
1076 		return emulate_mfspr(spr, rs, frame);
1077 	} else if ((instr & XFX) == 0x7c0003a6) {	/* mtspr */
1078 		rs = (instr &  0x3e00000) >> 21;
1079 		spr = (instr & 0x1ff800) >> 16;
1080 		return emulate_mtspr(spr, rs, frame);
1081 	} else if ((instr & 0xfc000ffe) == 0x7c0004ac) {	/* various sync */
1082 		powerpc_sync(); /* Do a heavy-weight sync */
1083 		frame->srr0 += 4;
1084 		return (0);
1085 	}
1086 
1087 #ifdef FPU_EMU
1088 	if (!(pcb->pcb_flags & PCB_FPREGS)) {
1089 		bzero(&pcb->pcb_fpu, sizeof(pcb->pcb_fpu));
1090 		pcb->pcb_flags |= PCB_FPREGS;
1091 	}
1092 	sig = fpu_emulate(frame, &pcb->pcb_fpu);
1093 #endif
1094 
1095 	return (sig);
1096 }
1097 
1098