1 /*	$NetBSD: netbsd32_machdep.c,v 1.109 2015/11/26 13:15:34 martin Exp $	*/
2 
3 /*
4  * Copyright (c) 1998, 2001 Matthew R. Green
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
29 #include <sys/cdefs.h>
30 __KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.109 2015/11/26 13:15:34 martin Exp $");
31 
32 #ifdef _KERNEL_OPT
33 #include "opt_compat_netbsd.h"
34 #include "opt_compat_sunos.h"
35 #include "opt_modular.h"
36 #include "opt_execfmt.h"
37 #include "firm_events.h"
38 #endif
39 
40 #include <sys/param.h>
41 #include <sys/exec.h>
42 #include <sys/exec_aout.h>
43 #include <sys/filedesc.h>
44 #include <sys/file.h>
45 #include <sys/proc.h>
46 #include <sys/signalvar.h>
47 #include <sys/systm.h>
48 #include <sys/core.h>
49 #include <sys/mount.h>
50 #include <sys/buf.h>
51 #include <sys/vnode.h>
52 #include <sys/select.h>
53 #include <sys/socketvar.h>
54 #include <sys/ucontext.h>
55 #include <sys/ioctl.h>
56 #include <sys/kmem.h>
57 
58 #include <dev/sun/event_var.h>
59 
60 #include <net/if.h>
61 #include <net/route.h>
62 
63 #include <netinet/in.h>
64 #include <netinet/in_var.h>
65 #include <netinet/igmp.h>
66 #include <netinet/igmp_var.h>
67 #include <netinet/ip_mroute.h>
68 
69 #include <compat/netbsd32/netbsd32.h>
70 #include <compat/netbsd32/netbsd32_ioctl.h>
71 #include <compat/netbsd32/netbsd32_syscallargs.h>
72 #include <compat/netbsd32/netbsd32_exec.h>
73 
74 #include <compat/sys/signal.h>
75 #include <compat/sys/signalvar.h>
76 #include <compat/sys/siginfo.h>
77 #include <compat/sys/ucontext.h>
78 
79 #include <machine/frame.h>
80 #include <machine/pcb.h>
81 #include <machine/reg.h>
82 #include <machine/vmparam.h>
83 #include <machine/vuid_event.h>
84 #include <machine/netbsd32_machdep.h>
85 #include <machine/userret.h>
86 
87 /* Provide a the name of the architecture we're emulating */
88 const char	machine32[] = "sparc";
89 const char	machine_arch32[] = "sparc";
90 
91 #if NFIRM_EVENTS > 0
92 static int ev_out32(struct firm_event *, int, struct uio *);
93 #endif
94 
95 /*
96  * Set up registers on exec.
97  *
98  * XXX this entire mess must be fixed
99  */
100 /* ARGSUSED */
101 void
netbsd32_setregs(struct lwp * l,struct exec_package * pack,vaddr_t stack)102 netbsd32_setregs(struct lwp *l, struct exec_package *pack, vaddr_t stack)
103 {
104 	struct proc *p = l->l_proc;
105 	struct trapframe64 *tf = l->l_md.md_tf;
106 	struct fpstate64 *fs;
107 	int64_t tstate;
108 
109 	/* Don't allow misaligned code by default */
110 	p->p_md.md_flags &= ~MDP_FIXALIGN;
111 
112 	/* Mark this as a 32-bit emulation */
113 	p->p_flag |= PK_32;
114 
115 	netbsd32_adjust_limits(p);
116 
117 	/* Setup the ev_out32 hook */
118 #if NFIRM_EVENTS > 0
119 	if (ev_out32_hook == NULL)
120 		ev_out32_hook = ev_out32;
121 #endif
122 
123 	/*
124 	 * Set the registers to 0 except for:
125 	 *	%o6: stack pointer, built in exec())
126 	 *	%tstate: (retain icc and xcc and cwp bits)
127 	 *	%g1: p->p_psstrp (used by crt0)
128 	 *	%tpc,%tnpc: entry point of program
129 	 */
130 	tstate = ((PSTATE_USER32)<<TSTATE_PSTATE_SHIFT)
131 		| (tf->tf_tstate & TSTATE_CWP);
132 	if ((fs = l->l_md.md_fpstate) != NULL) {
133 		/*
134 		 * We hold an FPU state.  If we own *the* FPU chip state
135 		 * we must get rid of it, and the only way to do that is
136 		 * to save it.  In any case, get rid of our FPU state.
137 		 */
138 		fpusave_lwp(l, false);
139 		pool_cache_put(fpstate_cache, fs);
140 		l->l_md.md_fpstate = NULL;
141 	}
142 	memset(tf, 0, sizeof *tf);
143 	tf->tf_tstate = tstate;
144 	tf->tf_global[1] = p->p_psstrp;
145 	tf->tf_pc = pack->ep_entry & ~3;
146 	tf->tf_npc = tf->tf_pc + 4;
147 
148 	stack -= sizeof(struct rwindow32);
149 	tf->tf_out[6] = stack;
150 	tf->tf_out[7] = 0;
151 }
152 
153 #ifdef COMPAT_16
154 /*
155  * NB: since this is a 32-bit address world, sf_scp and sf_sc
156  *	can't be a pointer since those are 64-bits wide.
157  */
158 struct sparc32_sigframe {
159 	int	sf_signo;		/* signal number */
160 	int	sf_code;		/* code */
161 	u_int	sf_scp;			/* SunOS user addr of sigcontext */
162 	int	sf_addr;		/* SunOS compat, always 0 for now */
163 	struct	netbsd32_sigcontext sf_sc;	/* actual sigcontext */
164 };
165 
166 #undef DEBUG
167 #ifdef DEBUG
168 extern int sigdebug;
169 #endif
170 
171 static void
netbsd32_sendsig_sigcontext(const ksiginfo_t * ksi,const sigset_t * mask)172 netbsd32_sendsig_sigcontext(const ksiginfo_t *ksi, const sigset_t *mask)
173 {
174 	int sig = ksi->ksi_signo;
175 	struct lwp *l = curlwp;
176 	struct proc *p = l->l_proc;
177 	struct sparc32_sigframe *fp;
178 	struct trapframe64 *tf;
179 	int addr, onstack, error;
180 	struct rwindow32 *oldsp, *newsp;
181 	register32_t sp;
182 	sig_t catcher = SIGACTION(p, sig).sa_handler;
183 	struct sparc32_sigframe sf;
184 	extern char netbsd32_sigcode[], netbsd32_esigcode[];
185 #define	szsigcode	(netbsd32_esigcode - netbsd32_sigcode)
186 
187 	tf = l->l_md.md_tf;
188 	/* Need to attempt to zero extend this 32-bit pointer */
189 	oldsp = (struct rwindow32 *)(u_long)(u_int)tf->tf_out[6];
190 	/* Do we need to jump onto the signal stack? */
191 	onstack =
192 	    (l->l_sigstk.ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 &&
193 	    (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0;
194 	if (onstack) {
195 		fp = (struct sparc32_sigframe *)((char *)l->l_sigstk.ss_sp +
196 					l->l_sigstk.ss_size);
197 		l->l_sigstk.ss_flags |= SS_ONSTACK;
198 	} else
199 		fp = (struct sparc32_sigframe *)oldsp;
200 	fp = (struct sparc32_sigframe *)((u_long)(fp - 1) & ~7);
201 
202 #ifdef DEBUG
203 	sigpid = p->p_pid;
204 	if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) {
205 		printf("sendsig: %s[%d] sig %d newusp %p scp %p oldsp %p\n",
206 		    p->p_comm, p->p_pid, sig, fp, &fp->sf_sc, oldsp);
207 		if (sigdebug & SDB_DDB) Debugger();
208 	}
209 #endif
210 	/*
211 	 * Now set up the signal frame.  We build it in kernel space
212 	 * and then copy it out.  We probably ought to just build it
213 	 * directly in user space....
214 	 */
215 	sf.sf_signo = sig;
216 	sf.sf_code = (u_int)ksi->ksi_trap;
217 #if defined(COMPAT_SUNOS) || defined(MODULAR)
218 	sf.sf_scp = (u_long)&fp->sf_sc;
219 #endif
220 	sf.sf_addr = 0;			/* XXX */
221 
222 	/*
223 	 * Build the signal context to be used by sigreturn.
224 	 */
225 	sf.sf_sc.sc_onstack = onstack;
226 	sf.sf_sc.sc_mask = *mask;
227 	sf.sf_sc.sc_sp = (u_long)oldsp;
228 	sf.sf_sc.sc_pc = tf->tf_pc;
229 	sf.sf_sc.sc_npc = tf->tf_npc;
230 	sf.sf_sc.sc_psr = TSTATECCR_TO_PSR(tf->tf_tstate); /* XXX */
231 	sf.sf_sc.sc_g1 = tf->tf_global[1];
232 	sf.sf_sc.sc_o0 = tf->tf_out[0];
233 
234 	/*
235 	 * Put the stack in a consistent state before we whack away
236 	 * at it.  Note that write_user_windows may just dump the
237 	 * registers into the pcb; we need them in the process's memory.
238 	 * We also need to make sure that when we start the signal handler,
239 	 * its %i6 (%fp), which is loaded from the newly allocated stack area,
240 	 * joins seamlessly with the frame it was in when the signal occurred,
241 	 * so that the debugger and _longjmp code can back up through it.
242 	 */
243 	sendsig_reset(l, sig);
244 	mutex_exit(p->p_lock);
245 	newsp = (struct rwindow32 *)((long)fp - sizeof(struct rwindow32));
246 	write_user_windows();
247 #ifdef DEBUG
248 	if ((sigdebug & SDB_KSTACK))
249 	    printf("sendsig: saving sf to %p, setting stack pointer %p to %p\n",
250 		   fp, &(((struct rwindow32 *)newsp)->rw_in[6]), oldsp);
251 #endif
252 	sp = NETBSD32PTR32I(oldsp);
253 	error = (rwindow_save(l) ||
254 	    copyout(&sf, fp, sizeof sf) ||
255 	    copyout(&sp, &(((struct rwindow32 *)newsp)->rw_in[6]),
256 	        sizeof(sp)));
257 	mutex_enter(p->p_lock);
258 	if (error) {
259 		/*
260 		 * Process has trashed its stack; give it an illegal
261 		 * instruction to halt it in its tracks.
262 		 */
263 #ifdef DEBUG
264 		mutex_exit(p->p_lock);
265 		if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
266 			printf("sendsig: window save or copyout error\n");
267 		printf("sendsig: stack was trashed trying to send sig %d, sending SIGILL\n", sig);
268 		if (sigdebug & SDB_DDB) Debugger();
269 		mutex_enter(p->p_lock);
270 #endif
271 		sigexit(l, SIGILL);
272 		/* NOTREACHED */
273 	}
274 
275 #ifdef DEBUG
276 	if (sigdebug & SDB_FOLLOW) {
277 		printf("sendsig: %s[%d] sig %d scp %p\n",
278 		       p->p_comm, p->p_pid, sig, &fp->sf_sc);
279 	}
280 #endif
281 	/*
282 	 * Arrange to continue execution at the code copied out in exec().
283 	 * It needs the function to call in %g1, and a new stack pointer.
284 	 */
285 	addr = p->p_psstrp - szsigcode;
286 	tf->tf_global[1] = (long)catcher;
287 	tf->tf_pc = addr;
288 	tf->tf_npc = addr + 4;
289 	tf->tf_out[6] = (uint64_t)(u_int)(u_long)newsp;
290 
291 	/* Remember that we're now on the signal stack. */
292 	if (onstack)
293 		l->l_sigstk.ss_flags |= SS_ONSTACK;
294 
295 #ifdef DEBUG
296 	if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) {
297 		mutex_exit(p->p_lock);
298 		printf("sendsig: about to return to catcher %p thru %p\n",
299 		       catcher, addr);
300 		if (sigdebug & SDB_DDB) Debugger();
301 		mutex_enter(p->p_lock);
302 	}
303 #endif
304 }
305 #endif
306 
307 struct sparc32_sigframe_siginfo {
308 	siginfo32_t sf_si;
309 	ucontext32_t sf_uc;
310 };
311 
312 static void
netbsd32_sendsig_siginfo(const ksiginfo_t * ksi,const sigset_t * mask)313 netbsd32_sendsig_siginfo(const ksiginfo_t *ksi, const sigset_t *mask)
314 {
315 	struct lwp *l = curlwp;
316 	struct proc *p = l->l_proc;
317 	struct sigacts *ps = p->p_sigacts;
318 	int onstack;
319 	int sig = ksi->ksi_signo;
320 	ucontext32_t uc;
321 	struct sparc32_sigframe_siginfo *fp;
322 	siginfo32_t si32;
323 	netbsd32_intptr_t catcher;
324 	struct trapframe64 *tf = l->l_md.md_tf;
325 	struct rwindow32 *oldsp, *newsp;
326 	register32_t sp;
327 	int ucsz, error;
328 
329 	/* Need to attempt to zero extend this 32-bit pointer */
330 	oldsp = (struct rwindow32*)(u_long)(u_int)tf->tf_out[6];
331 	/* Do we need to jump onto the signal stack? */
332 	onstack =
333 	    (l->l_sigstk.ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 &&
334 	    (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0;
335 
336 	/* Allocate space for the signal handler context. */
337 	if (onstack)
338 		fp = (struct sparc32_sigframe_siginfo *)
339 		    ((char *)l->l_sigstk.ss_sp +
340 					  l->l_sigstk.ss_size);
341 	else
342 		fp = (struct sparc32_sigframe_siginfo *)oldsp;
343 	fp = (struct sparc32_sigframe_siginfo*)((u_long)(fp - 1) & ~7);
344 
345 	/*
346 	 * Build the signal context to be used by sigreturn.
347 	 */
348 	memset(&uc, 0, sizeof uc);
349 	uc.uc_flags = _UC_SIGMASK |
350 		((l->l_sigstk.ss_flags & SS_ONSTACK)
351 			? _UC_SETSTACK : _UC_CLRSTACK);
352 	uc.uc_sigmask = *mask;
353 	uc.uc_link = (uint32_t)(uintptr_t)l->l_ctxlink;
354 
355 	sendsig_reset(l, sig);
356 
357 	/*
358 	 * Now copy the stack contents out to user space.
359 	 * We need to make sure that when we start the signal handler,
360 	 * its %i6 (%fp), which is loaded from the newly allocated stack area,
361 	 * joins seamlessly with the frame it was in when the signal occurred,
362 	 * so that the debugger and _longjmp code can back up through it.
363 	 * Since we're calling the handler directly, allocate a full size
364 	 * C stack frame.
365 	 */
366 	mutex_exit(p->p_lock);
367 	cpu_getmcontext32(l, &uc.uc_mcontext, &uc.uc_flags);
368 	netbsd32_si_to_si32(&si32, (const siginfo_t *)&ksi->ksi_info);
369 	ucsz = (int)(intptr_t)&uc.__uc_pad - (int)(intptr_t)&uc;
370 	newsp = (struct rwindow32*)((intptr_t)fp - sizeof(struct frame32));
371 	sp = NETBSD32PTR32I(oldsp);
372 	error = (copyout(&si32, &fp->sf_si, sizeof si32) ||
373 	    copyout(&uc, &fp->sf_uc, ucsz) ||
374 	    copyout(&sp, &newsp->rw_in[6], sizeof(sp)));
375 	mutex_enter(p->p_lock);
376 
377 	if (error) {
378 		/*
379 		 * Process has trashed its stack; give it an illegal
380 		 * instruction to halt it in its tracks.
381 		 */
382 		sigexit(l, SIGILL);
383 		/* NOTREACHED */
384 	}
385 
386 	switch (ps->sa_sigdesc[sig].sd_vers) {
387 	default:
388 		/* Unsupported trampoline version; kill the process. */
389 		sigexit(l, SIGILL);
390 	case 2:
391 		/*
392 		 * Arrange to continue execution at the user's handler.
393 		 * It needs a new stack pointer, a return address and
394 		 * three arguments: (signo, siginfo *, ucontext *).
395 		 */
396 		catcher = (intptr_t)SIGACTION(p, sig).sa_handler;
397 		tf->tf_pc = catcher;
398 		tf->tf_npc = catcher + 4;
399 		tf->tf_out[0] = sig;
400 		tf->tf_out[1] = (intptr_t)&fp->sf_si;
401 		tf->tf_out[2] = (intptr_t)&fp->sf_uc;
402 		tf->tf_out[6] = (intptr_t)newsp;
403 		tf->tf_out[7] = (intptr_t)ps->sa_sigdesc[sig].sd_tramp - 8;
404 		break;
405 	}
406 
407 	/* Remember that we're now on the signal stack. */
408 	if (onstack)
409 		l->l_sigstk.ss_flags |= SS_ONSTACK;
410 }
411 
412 void
netbsd32_sendsig(const ksiginfo_t * ksi,const sigset_t * mask)413 netbsd32_sendsig(const ksiginfo_t *ksi, const sigset_t *mask)
414 {
415 #ifdef COMPAT_16
416 	if (curproc->p_sigacts->sa_sigdesc[ksi->ksi_signo].sd_vers < 2)
417 		netbsd32_sendsig_sigcontext(ksi, mask);
418 	else
419 #endif
420 		netbsd32_sendsig_siginfo(ksi, mask);
421 }
422 
423 #undef DEBUG
424 
425 #ifdef COMPAT_13
426 int
compat_13_netbsd32_sigreturn(struct lwp * l,const struct compat_13_netbsd32_sigreturn_args * uap,register_t * retval)427 compat_13_netbsd32_sigreturn(struct lwp *l, const struct compat_13_netbsd32_sigreturn_args *uap, register_t *retval)
428 {
429 	/* {
430 		syscallarg(struct netbsd32_sigcontext13 *) sigcntxp;
431 	} */
432 	struct netbsd32_sigcontext13 *scp;
433 	struct netbsd32_sigcontext13 sc;
434 	struct trapframe64 *tf;
435 	struct proc *p = l->l_proc;
436 	sigset_t mask;
437 
438 	/* First ensure consistent stack state (see sendsig). */
439 	write_user_windows();
440 	if (rwindow_save(l)) {
441 #ifdef DEBUG
442 		printf("compat_13_netbsd32_sigreturn: rwindow_save(%p) failed, sending SIGILL\n", p);
443 		Debugger();
444 #endif
445 		mutex_enter(p->p_lock);
446 		sigexit(l, SIGILL);
447 	}
448 #ifdef DEBUG
449 	if (sigdebug & SDB_FOLLOW) {
450 		printf("compat_13_netbsd32_sigreturn: %s[%d], sigcntxp %p\n",
451 		    p->p_comm, p->p_pid, SCARG(uap, sigcntxp));
452 		if (sigdebug & SDB_DDB) Debugger();
453 	}
454 #endif
455 	scp = (struct netbsd32_sigcontext13 *)(u_long)SCARG(uap, sigcntxp);
456  	if ((vaddr_t)scp & 3 || (copyin((void *)scp, &sc, sizeof sc) != 0))
457 	{
458 #ifdef DEBUG
459 		printf("compat_13_netbsd32_sigreturn: copyin failed\n");
460 		Debugger();
461 #endif
462 		return (EINVAL);
463 	}
464 	scp = &sc;
465 
466 	tf = l->l_md.md_tf;
467 	/*
468 	 * Only the icc bits in the psr are used, so it need not be
469 	 * verified.  pc and npc must be multiples of 4.  This is all
470 	 * that is required; if it holds, just do it.
471 	 */
472 	if (((sc.sc_pc | sc.sc_npc) & 3) != 0)
473 #ifdef DEBUG
474 	{
475 		printf("compat_13_netbsd32_sigreturn: pc %p or npc %p invalid\n", sc.sc_pc, sc.sc_npc);
476 		Debugger();
477 		return (EINVAL);
478 	}
479 #else
480 		return (EINVAL);
481 #endif
482 	/* take only psr ICC field */
483 	tf->tf_tstate = (int64_t)(tf->tf_tstate & ~TSTATE_CCR) | PSRCC_TO_TSTATE(sc.sc_psr);
484 	tf->tf_pc = (int64_t)sc.sc_pc;
485 	tf->tf_npc = (int64_t)sc.sc_npc;
486 	tf->tf_global[1] = (int64_t)sc.sc_g1;
487 	tf->tf_out[0] = (int64_t)sc.sc_o0;
488 	tf->tf_out[6] = (int64_t)sc.sc_sp;
489 #ifdef DEBUG
490 	if (sigdebug & SDB_FOLLOW) {
491 		printf("compat_13_netbsd32_sys_sigreturn: return trapframe pc=%p sp=%p tstate=%x\n",
492 		       (int)tf->tf_pc, (int)tf->tf_out[6], (int)tf->tf_tstate);
493 		if (sigdebug & SDB_DDB) Debugger();
494 	}
495 #endif
496 	mutex_enter(p->p_lock);
497 	if (scp->sc_onstack & SS_ONSTACK)
498 		l->l_sigstk.ss_flags |= SS_ONSTACK;
499 	else
500 		l->l_sigstk.ss_flags &= ~SS_ONSTACK;
501 	/* Restore signal mask */
502 	native_sigset13_to_sigset((sigset13_t *)&scp->sc_mask, &mask);
503 	(void) sigprocmask1(l, SIG_SETMASK, &mask, 0);
504 	mutex_exit(p->p_lock);
505 
506 	return (EJUSTRETURN);
507 }
508 #endif
509 
510 /*
511  * System call to cleanup state after a signal
512  * has been taken.  Reset signal mask and
513  * stack state from context left by sendsig (above),
514  * and return to the given trap frame (if there is one).
515  * Check carefully to make sure that the user has not
516  * modified the state to gain improper privileges or to cause
517  * a machine fault.
518  */
519 /* ARGSUSED */
520 int
compat_16_netbsd32___sigreturn14(struct lwp * l,const struct compat_16_netbsd32___sigreturn14_args * uap,register_t * retval)521 compat_16_netbsd32___sigreturn14(struct lwp *l, const struct compat_16_netbsd32___sigreturn14_args *uap, register_t *retval)
522 {
523 	/* {
524 		syscallarg(struct sigcontext *) sigcntxp;
525 	} */
526 	struct netbsd32_sigcontext sc, *scp;
527 	struct trapframe64 *tf;
528 	struct proc *p = l->l_proc;
529 
530 	/* First ensure consistent stack state (see sendsig). */
531 	write_user_windows();
532 	if (rwindow_save(l)) {
533 #ifdef DEBUG
534 		printf("netbsd32_sigreturn14: rwindow_save(%p) failed, sending SIGILL\n", p);
535 		Debugger();
536 #endif
537 		mutex_enter(p->p_lock);
538 		sigexit(l, SIGILL);
539 	}
540 #ifdef DEBUG
541 	if (sigdebug & SDB_FOLLOW) {
542 		printf("netbsd32_sigreturn14: %s[%d], sigcntxp %p\n",
543 		    p->p_comm, p->p_pid, SCARG(uap, sigcntxp));
544 		if (sigdebug & SDB_DDB) Debugger();
545 	}
546 #endif
547 	scp = (struct netbsd32_sigcontext *)(u_long)SCARG(uap, sigcntxp);
548  	if ((vaddr_t)scp & 3 || (copyin((void *)scp, &sc, sizeof sc) != 0))
549 	{
550 #ifdef DEBUG
551 		printf("netbsd32_sigreturn14: copyin failed: scp=%p\n", scp);
552 		Debugger();
553 #endif
554 		return (EINVAL);
555 	}
556 	scp = &sc;
557 
558 	tf = l->l_md.md_tf;
559 	/*
560 	 * Only the icc bits in the psr are used, so it need not be
561 	 * verified.  pc and npc must be multiples of 4.  This is all
562 	 * that is required; if it holds, just do it.
563 	 */
564 	if (((sc.sc_pc | sc.sc_npc) & 3) != 0 || (sc.sc_pc == 0) || (sc.sc_npc == 0))
565 #ifdef DEBUG
566 	{
567 		printf("netbsd32_sigreturn14: pc %p or npc %p invalid\n", sc.sc_pc, sc.sc_npc);
568 		Debugger();
569 		return (EINVAL);
570 	}
571 #else
572 		return (EINVAL);
573 #endif
574 	/* take only psr ICC field */
575 	tf->tf_tstate = (int64_t)(tf->tf_tstate & ~TSTATE_CCR) | PSRCC_TO_TSTATE(sc.sc_psr);
576 	tf->tf_pc = (int64_t)sc.sc_pc;
577 	tf->tf_npc = (int64_t)sc.sc_npc;
578 	tf->tf_global[1] = (int64_t)sc.sc_g1;
579 	tf->tf_out[0] = (int64_t)sc.sc_o0;
580 	tf->tf_out[6] = (int64_t)sc.sc_sp;
581 #ifdef DEBUG
582 	if (sigdebug & SDB_FOLLOW) {
583 		printf("netbsd32_sigreturn14: return trapframe pc=%p sp=%p tstate=%llx\n",
584 		       (vaddr_t)tf->tf_pc, (vaddr_t)tf->tf_out[6], tf->tf_tstate);
585 		if (sigdebug & SDB_DDB) Debugger();
586 	}
587 #endif
588 
589 	/* Restore signal stack. */
590 	mutex_enter(p->p_lock);
591 	if (sc.sc_onstack & SS_ONSTACK)
592 		l->l_sigstk.ss_flags |= SS_ONSTACK;
593 	else
594 		l->l_sigstk.ss_flags &= ~SS_ONSTACK;
595 	/* Restore signal mask. */
596 	(void) sigprocmask1(l, SIG_SETMASK, &sc.sc_mask, 0);
597 	mutex_exit(p->p_lock);
598 
599 	return (EJUSTRETURN);
600 }
601 
602 /* Unfortunately we need to convert v9 trapframe to v8 regs */
603 int
netbsd32_process_read_regs(struct lwp * l,struct reg32 * regs)604 netbsd32_process_read_regs(struct lwp *l, struct reg32 *regs)
605 {
606 	struct trapframe64* tf = l->l_md.md_tf;
607 	int i;
608 
609 	/*
610 	 * Um, we should only do this conversion for 32-bit emulation
611 	 * or when running 32-bit mode.  We really need to pass in a
612 	 * 32-bit emulation flag!
613 	 */
614 
615 	regs->r_psr = TSTATECCR_TO_PSR(tf->tf_tstate);
616 	regs->r_pc = tf->tf_pc;
617 	regs->r_npc = tf->tf_npc;
618 	regs->r_y = tf->tf_y;
619 	for (i = 0; i < 8; i++) {
620 		regs->r_global[i] = tf->tf_global[i];
621 		regs->r_out[i] = tf->tf_out[i];
622 	}
623 	/* We should also write out the ins and locals.  See signal stuff */
624 	return (0);
625 }
626 
627 #if 0
628 int
629 netbsd32_process_write_regs(struct lwp *l, const struct reg32 *regs)
630 {
631 	struct trapframe64* tf = p->p_md.md_tf;
632 	int i;
633 
634 	tf->tf_pc = regs->r_pc;
635 	tf->tf_npc = regs->r_npc;
636 	tf->tf_y = regs->r_pc;
637 	for (i = 0; i < 8; i++) {
638 		tf->tf_global[i] = regs->r_global[i];
639 		tf->tf_out[i] = regs->r_out[i];
640 	}
641 	/* We should also read in the ins and locals.  See signal stuff */
642 	tf->tf_tstate = (int64_t)(tf->tf_tstate & ~TSTATE_CCR) |
643 		PSRCC_TO_TSTATE(regs->r_psr);
644 	return (0);
645 }
646 #endif
647 
648 int
netbsd32_process_read_fpregs(struct lwp * l,struct fpreg32 * regs,size_t * sz)649 netbsd32_process_read_fpregs(struct lwp *l, struct fpreg32 *regs, size_t *sz)
650 {
651 	extern const struct fpstate64 initfpstate;
652 	const struct fpstate64	*statep = &initfpstate;
653 	int i;
654 
655 	if (l->l_md.md_fpstate)
656 		statep = l->l_md.md_fpstate;
657 	for (i = 0; i < 32; i++)
658 		regs->fr_regs[i] = statep->fs_regs[i];
659 	regs->fr_fsr = statep->fs_fsr;
660 
661 	return 0;
662 }
663 
664 #if 0
665 int
666 netbsd32_process_write_fpregs(struct lwp *l, const struct fpreg32 *regs)
667 {
668 	struct fpstate64	*statep;
669 	int i;
670 
671 	statep = l->l_md.md_fpstate;
672 	if (statep == NULL)
673 		return EINVAL;
674 	for (i = 0; i < 32; i++)
675 		statep->fs_regs[i] = regs->fr_regs[i];
676 	statep->fs_fsr = regs->fr_fsr;
677 	statep->fs_qsize = 0;
678 
679 	return 0;
680 }
681 #endif
682 
683 /*
684  * 32-bit version of cpu_coredump.
685  */
686 int
cpu_coredump32(struct lwp * l,struct coredump_iostate * iocookie,struct core32 * chdr)687 cpu_coredump32(struct lwp *l, struct coredump_iostate *iocookie,
688     struct core32 *chdr)
689 {
690 	int i, error;
691 	struct md_coredump32 md_core;
692 	struct coreseg32 cseg;
693 
694 	if (iocookie == NULL) {
695 		CORE_SETMAGIC(*chdr, COREMAGIC, MID_MACHINE, 0);
696 		chdr->c_hdrsize = ALIGN(sizeof(*chdr));
697 		chdr->c_seghdrsize = ALIGN(sizeof(cseg));
698 		chdr->c_cpusize = sizeof(md_core);
699 		chdr->c_nseg++;
700 		return 0;
701 	}
702 
703 	/* Fake a v8 trapframe */
704 	md_core.md_tf.tf_psr = TSTATECCR_TO_PSR(l->l_md.md_tf->tf_tstate);
705 	md_core.md_tf.tf_pc = l->l_md.md_tf->tf_pc;
706 	md_core.md_tf.tf_npc = l->l_md.md_tf->tf_npc;
707 	md_core.md_tf.tf_y = l->l_md.md_tf->tf_y;
708 	for (i=0; i<8; i++) {
709 		md_core.md_tf.tf_global[i] = l->l_md.md_tf->tf_global[i];
710 		md_core.md_tf.tf_out[i] = l->l_md.md_tf->tf_out[i];
711 	}
712 
713 	if (l->l_md.md_fpstate) {
714 		fpusave_lwp(l, true);
715 		/* Copy individual fields */
716 		for (i=0; i<32; i++)
717 			md_core.md_fpstate.fs_regs[i] =
718 				l->l_md.md_fpstate->fs_regs[i];
719 		md_core.md_fpstate.fs_fsr = l->l_md.md_fpstate->fs_fsr;
720 		i = md_core.md_fpstate.fs_qsize = l->l_md.md_fpstate->fs_qsize;
721 		/* Should always be zero */
722 		while (i--)
723 			md_core.md_fpstate.fs_queue[i] =
724 				l->l_md.md_fpstate->fs_queue[i];
725 	} else
726 		memset(&md_core.md_fpstate, 0,
727 		      sizeof(md_core.md_fpstate));
728 
729 	CORE_SETMAGIC(cseg, CORESEGMAGIC, MID_MACHINE, CORE_CPU);
730 	cseg.c_addr = 0;
731 	cseg.c_size = chdr->c_cpusize;
732 
733 	error = coredump_write(iocookie, UIO_SYSSPACE, &cseg,
734 	    chdr->c_seghdrsize);
735 	if (error)
736 		return error;
737 
738 	return coredump_write(iocookie, UIO_SYSSPACE, &md_core,
739 	    sizeof(md_core));
740 }
741 
742 void netbsd32_cpu_getmcontext(struct lwp *, mcontext_t  *, unsigned int *);
743 
744 void
netbsd32_cpu_getmcontext(struct lwp * l,mcontext_t * mcp,unsigned int * flags)745 netbsd32_cpu_getmcontext(
746 	struct lwp *l,
747 	/* netbsd32_mcontext_t XXX */mcontext_t  *mcp,
748 	unsigned int *flags)
749 {
750 #if 0
751 /* XXX */
752 	greg32_t *gr = mcp->__gregs;
753 	const struct trapframe64 *tf = l->l_md.md_tf;
754 
755 	/* First ensure consistent stack state (see sendsig). */ /* XXX? */
756 	write_user_windows();
757 	if (rwindow_save(l)) {
758 		mutex_enter(l->l_proc->p_lock);
759 		sigexit(l, SIGILL);
760 	}
761 
762 	/* For now: Erase any random indicators for optional state. */
763 	(void)memset(mcp, 0, sizeof (*mcp));
764 
765 	/* Save general register context. */
766 	gr[_REG_PSR] = TSTATECCR_TO_PSR(tf->tf_tstate);
767 	gr[_REG_PC]  = tf->tf_pc;
768 	gr[_REG_nPC] = tf->tf_npc;
769 	gr[_REG_Y]   = tf->tf_y;
770 	gr[_REG_G1]  = tf->tf_global[1];
771 	gr[_REG_G2]  = tf->tf_global[2];
772 	gr[_REG_G3]  = tf->tf_global[3];
773 	gr[_REG_G4]  = tf->tf_global[4];
774 	gr[_REG_G5]  = tf->tf_global[5];
775 	gr[_REG_G6]  = tf->tf_global[6];
776 	gr[_REG_G7]  = tf->tf_global[7];
777 	gr[_REG_O0]  = tf->tf_out[0];
778 	gr[_REG_O1]  = tf->tf_out[1];
779 	gr[_REG_O2]  = tf->tf_out[2];
780 	gr[_REG_O3]  = tf->tf_out[3];
781 	gr[_REG_O4]  = tf->tf_out[4];
782 	gr[_REG_O5]  = tf->tf_out[5];
783 	gr[_REG_O6]  = tf->tf_out[6];
784 	gr[_REG_O7]  = tf->tf_out[7];
785 	*flags |= (_UC_CPU|_UC_TLSBASE);
786 
787 	mcp->__gwins = 0;
788 
789 
790 	/* Save FP register context, if any. */
791 	if (l->l_md.md_fpstate != NULL) {
792 		struct fpstate *fsp;
793 		netbsd32_fpregset_t *fpr = &mcp->__fpregs;
794 
795 		/*
796 		 * If our FP context is currently held in the FPU, take a
797 		 * private snapshot - lazy FPU context switching can deal
798 		 * with it later when it becomes necessary.
799 		 * Otherwise, get it from the process's save area.
800 		 */
801 		fpusave_lwp(l, true);
802 		fsp = l->l_md.md_fpstate;
803 		memcpy(&fpr->__fpu_fr, fsp->fs_regs, sizeof (fpr->__fpu_fr));
804 		mcp->__fpregs.__fpu_q = NULL;	/* `Need more info.' */
805 		mcp->__fpregs.__fpu_fsr = fs.fs_fsr;
806 		mcp->__fpregs.__fpu_qcnt = 0 /*fs.fs_qsize*/; /* See above */
807 		mcp->__fpregs.__fpu_q_entrysize =
808 		    sizeof (struct netbsd32_fq);
809 		mcp->__fpregs.__fpu_en = 1;
810 		*flags |= _UC_FPU;
811 	} else {
812 		mcp->__fpregs.__fpu_en = 0;
813 	}
814 
815 	mcp->__xrs.__xrs_id = 0;	/* Solaris extension? */
816 #endif
817 }
818 
819 int netbsd32_cpu_setmcontext(struct lwp *, mcontext_t *, unsigned int);
820 
821 int
netbsd32_cpu_setmcontext(struct lwp * l,mcontext_t * mcp,unsigned int flags)822 netbsd32_cpu_setmcontext(
823 	struct lwp *l,
824 	/* XXX const netbsd32_*/mcontext_t *mcp,
825 	unsigned int flags)
826 {
827 #ifdef NOT_YET
828 /* XXX */
829 	greg32_t *gr = mcp->__gregs;
830 	struct trapframe64 *tf = l->l_md.md_tf;
831 
832 	/* First ensure consistent stack state (see sendsig). */
833 	write_user_windows();
834 	if (rwindow_save(p)) {
835 		mutex_enter(l->l_proc->p_lock);
836 		sigexit(p, SIGILL);
837 	}
838 
839 	if ((flags & _UC_CPU) != 0) {
840 		/*
841 	 	 * Only the icc bits in the psr are used, so it need not be
842 	 	 * verified.  pc and npc must be multiples of 4.  This is all
843 	 	 * that is required; if it holds, just do it.
844 		 */
845 		if (((gr[_REG_PC] | gr[_REG_nPC]) & 3) != 0 ||
846 		    gr[_REG_PC] == 0 || gr[_REG_nPC] == 0)
847 			return (EINVAL);
848 
849 		/* Restore general register context. */
850 		/* take only tstate CCR (and ASI) fields */
851 		tf->tf_tstate = (tf->tf_tstate & ~TSTATE_CCR) |
852 		    PSRCC_TO_TSTATE(gr[_REG_PSR]);
853 		tf->tf_pc        = (uint64_t)gr[_REG_PC];
854 		tf->tf_npc       = (uint64_t)gr[_REG_nPC];
855 		tf->tf_y         = (uint64_t)gr[_REG_Y];
856 		tf->tf_global[1] = (uint64_t)gr[_REG_G1];
857 		tf->tf_global[2] = (uint64_t)gr[_REG_G2];
858 		tf->tf_global[3] = (uint64_t)gr[_REG_G3];
859 		tf->tf_global[4] = (uint64_t)gr[_REG_G4];
860 		tf->tf_global[5] = (uint64_t)gr[_REG_G5];
861 		tf->tf_global[6] = (uint64_t)gr[_REG_G6];
862 		tf->tf_global[7] = (uint64_t)gr[_REG_G7];
863 		tf->tf_out[0]    = (uint64_t)gr[_REG_O0];
864 		tf->tf_out[1]    = (uint64_t)gr[_REG_O1];
865 		tf->tf_out[2]    = (uint64_t)gr[_REG_O2];
866 		tf->tf_out[3]    = (uint64_t)gr[_REG_O3];
867 		tf->tf_out[4]    = (uint64_t)gr[_REG_O4];
868 		tf->tf_out[5]    = (uint64_t)gr[_REG_O5];
869 		tf->tf_out[6]    = (uint64_t)gr[_REG_O6];
870 		tf->tf_out[7]    = (uint64_t)gr[_REG_O7];
871 		/* %asi restored above; %fprs not yet supported. */
872 
873 		/* XXX mcp->__gwins */
874 	}
875 
876 	/* Restore FP register context, if any. */
877 	if ((flags & _UC_FPU) != 0 && mcp->__fpregs.__fpu_en != 0) {
878 		struct fpstate *fsp;
879 		const netbsd32_fpregset_t *fpr = &mcp->__fpregs;
880 		int reload = 0;
881 
882 		/*
883 		 * If we're the current FPU owner, simply reload it from
884 		 * the supplied context.  Otherwise, store it into the
885 		 * process' FPU save area (which is used to restore from
886 		 * by lazy FPU context switching); allocate it if necessary.
887 		 */
888 		/*
889 		 * XXX Should we really activate the supplied FPU context
890 		 * XXX immediately or just fault it in later?
891 		 */
892 		if ((fsp = l->l_md.md_fpstate) == NULL) {
893 			fsp = pool_cache_get(fpstate_cache, PR_WAITOK);
894 			l->l_md.md_fpstate = fsp;
895 		} else {
896 			/* Drop the live context on the floor. */
897 			fpusave_lwp(l, false);
898 			reload = 1;
899 		}
900 		/* Note: sizeof fpr->__fpu_fr <= sizeof fsp->fs_regs. */
901 		memcpy(fsp->fs_regs, fpr->__fpu_fr, sizeof (fpr->__fpu_fr));
902 		fsp->fs_fsr = fpr->__fpu_fsr;	/* don't care about fcc1-3 */
903 		fsp->fs_qsize = 0;
904 
905 #if 0
906 		/* Need more info! */
907 		mcp->__fpregs.__fpu_q = NULL;	/* `Need more info.' */
908 		mcp->__fpregs.__fpu_qcnt = 0 /*fs.fs_qsize*/; /* See above */
909 #endif
910 
911 		/* Reload context again, if necessary. */
912 		if (reload)
913 			loadfpstate(fsp);
914 	}
915 
916 	/* XXX mcp->__xrs */
917 	/* XXX mcp->__asrs */
918 #endif
919 	return (0);
920 }
921 
922 #if NFIRM_EVENTS > 0
923 /*
924  * Write out a series of 32-bit firm_events.
925  */
926 int
ev_out32(struct firm_event * e,int n,struct uio * uio)927 ev_out32(struct firm_event *e, int n, struct uio *uio)
928 {
929 	struct firm_event32 e32;
930 	int error = 0;
931 
932 	while (n-- && error == 0) {
933 		e32.id = e->id;
934 		e32.value = e->value;
935 		e32.time.tv_sec = e->time.tv_sec;
936 		e32.time.tv_usec = e->time.tv_usec;
937 		error = uiomove((void *)&e32, sizeof(e32), uio);
938 		e++;
939 	}
940 	return (error);
941 }
942 #endif
943 
944 /*
945  * ioctl code
946  */
947 
948 #include <dev/sun/fbio.h>
949 #include <machine/openpromio.h>
950 
951 /* from arch/sparc/include/fbio.h */
952 #if 0
953 /* unused */
954 #define	FBIOGINFO	_IOR('F', 2, struct fbinfo)
955 #endif
956 
957 struct netbsd32_fbcmap {
958 	int	index;		/* first element (0 origin) */
959 	int	count;		/* number of elements */
960 	netbsd32_u_charp	red;		/* red color map elements */
961 	netbsd32_u_charp	green;		/* green color map elements */
962 	netbsd32_u_charp	blue;		/* blue color map elements */
963 };
964 #if 1
965 #define	FBIOPUTCMAP32	_IOW('F', 3, struct netbsd32_fbcmap)
966 #define	FBIOGETCMAP32	_IOW('F', 4, struct netbsd32_fbcmap)
967 #endif
968 
969 struct netbsd32_fbcursor {
970 	short set;		/* what to set */
971 	short enable;		/* enable/disable cursor */
972 	struct fbcurpos pos;	/* cursor's position */
973 	struct fbcurpos hot;	/* cursor's hot spot */
974 	struct netbsd32_fbcmap cmap;	/* color map info */
975 	struct fbcurpos size;	/* cursor's bit map size */
976 	netbsd32_charp image;	/* cursor's image bits */
977 	netbsd32_charp mask;	/* cursor's mask bits */
978 };
979 #if 1
980 #define FBIOSCURSOR32	_IOW('F', 24, struct netbsd32_fbcursor)
981 #define FBIOGCURSOR32	_IOWR('F', 25, struct netbsd32_fbcursor)
982 #endif
983 
984 /* from arch/sparc/include/openpromio.h */
985 struct netbsd32_opiocdesc {
986 	int	op_nodeid;		/* passed or returned node id */
987 	int	op_namelen;		/* length of op_name */
988 	netbsd32_charp op_name;		/* pointer to field name */
989 	int	op_buflen;		/* length of op_buf (value-result) */
990 	netbsd32_charp op_buf;		/* pointer to field value */
991 };
992 #if 1
993 #define	OPIOCGET32	_IOWR('O', 1, struct netbsd32_opiocdesc) /* get openprom field */
994 #define	OPIOCSET32	_IOW('O', 2, struct netbsd32_opiocdesc) /* set openprom field */
995 #define	OPIOCNEXTPROP32	_IOWR('O', 3, struct netbsd32_opiocdesc) /* get next property */
996 #endif
997 
998 /* prototypes for the converters */
999 static inline void netbsd32_to_fbcmap(struct netbsd32_fbcmap *,
1000 					struct fbcmap *, u_long);
1001 static inline void netbsd32_to_fbcursor(struct netbsd32_fbcursor *,
1002 					  struct fbcursor *, u_long);
1003 static inline void netbsd32_to_opiocdesc(struct netbsd32_opiocdesc *,
1004 					   struct opiocdesc *, u_long);
1005 
1006 static inline void netbsd32_from_fbcmap(struct fbcmap *,
1007 					  struct netbsd32_fbcmap *, u_long);
1008 static inline void netbsd32_from_fbcursor(struct fbcursor *,
1009 					    struct netbsd32_fbcursor *, u_long);
1010 static inline void netbsd32_from_opiocdesc(struct opiocdesc *,
1011 					     struct netbsd32_opiocdesc *,
1012 					     u_long);
1013 
1014 /* convert to/from different structures */
1015 static inline void
netbsd32_to_fbcmap(struct netbsd32_fbcmap * s32p,struct fbcmap * p,u_long cmd)1016 netbsd32_to_fbcmap(struct netbsd32_fbcmap *s32p, struct fbcmap *p, u_long cmd)
1017 {
1018 
1019 	p->index = s32p->index;
1020 	p->count = s32p->count;
1021 	p->red = NETBSD32PTR64(s32p->red);
1022 	p->green = NETBSD32PTR64(s32p->green);
1023 	p->blue = NETBSD32PTR64(s32p->blue);
1024 }
1025 
1026 static inline void
netbsd32_to_fbcursor(struct netbsd32_fbcursor * s32p,struct fbcursor * p,u_long cmd)1027 netbsd32_to_fbcursor(struct netbsd32_fbcursor *s32p, struct fbcursor *p, u_long cmd)
1028 {
1029 
1030 	p->set = s32p->set;
1031 	p->enable = s32p->enable;
1032 	p->pos = s32p->pos;
1033 	p->hot = s32p->hot;
1034 	netbsd32_to_fbcmap(&s32p->cmap, &p->cmap, cmd);
1035 	p->size = s32p->size;
1036 	p->image = NETBSD32PTR64(s32p->image);
1037 	p->mask = NETBSD32PTR64(s32p->mask);
1038 }
1039 
1040 static inline void
netbsd32_to_opiocdesc(struct netbsd32_opiocdesc * s32p,struct opiocdesc * p,u_long cmd)1041 netbsd32_to_opiocdesc(struct netbsd32_opiocdesc *s32p, struct opiocdesc *p, u_long cmd)
1042 {
1043 
1044 	p->op_nodeid = s32p->op_nodeid;
1045 	p->op_namelen = s32p->op_namelen;
1046 	p->op_name = NETBSD32PTR64(s32p->op_name);
1047 	p->op_buflen = s32p->op_buflen;
1048 	p->op_buf = NETBSD32PTR64(s32p->op_buf);
1049 }
1050 
1051 static inline void
netbsd32_from_fbcmap(struct fbcmap * p,struct netbsd32_fbcmap * s32p,u_long cmd)1052 netbsd32_from_fbcmap(struct fbcmap *p, struct netbsd32_fbcmap *s32p, u_long cmd)
1053 {
1054 
1055 	s32p->index = p->index;
1056 	s32p->count = p->count;
1057 /* filled in */
1058 #if 0
1059 	s32p->red = (netbsd32_u_charp)p->red;
1060 	s32p->green = (netbsd32_u_charp)p->green;
1061 	s32p->blue = (netbsd32_u_charp)p->blue;
1062 #endif
1063 }
1064 
1065 static inline void
netbsd32_from_fbcursor(struct fbcursor * p,struct netbsd32_fbcursor * s32p,u_long cmd)1066 netbsd32_from_fbcursor(struct fbcursor *p, struct netbsd32_fbcursor *s32p, u_long cmd)
1067 {
1068 
1069 	s32p->set = p->set;
1070 	s32p->enable = p->enable;
1071 	s32p->pos = p->pos;
1072 	s32p->hot = p->hot;
1073 	netbsd32_from_fbcmap(&p->cmap, &s32p->cmap, cmd);
1074 	s32p->size = p->size;
1075 /* filled in */
1076 #if 0
1077 	s32p->image = (netbsd32_charp)p->image;
1078 	s32p->mask = (netbsd32_charp)p->mask;
1079 #endif
1080 }
1081 
1082 static inline void
netbsd32_from_opiocdesc(struct opiocdesc * p,struct netbsd32_opiocdesc * s32p,u_long cmd)1083 netbsd32_from_opiocdesc(struct opiocdesc *p, struct netbsd32_opiocdesc *s32p, u_long cmd)
1084 {
1085 
1086 	s32p->op_nodeid = p->op_nodeid;
1087 	s32p->op_namelen = p->op_namelen;
1088 	NETBSD32PTR32(s32p->op_name, p->op_name);
1089 	s32p->op_buflen = p->op_buflen;
1090 	NETBSD32PTR32(s32p->op_buf, p->op_buf);
1091 }
1092 
1093 int
netbsd32_md_ioctl(struct file * fp,netbsd32_u_long cmd,void * data32,struct lwp * l)1094 netbsd32_md_ioctl(struct file *fp, netbsd32_u_long cmd, void *data32, struct lwp *l)
1095 {
1096 	u_int size;
1097 	void *data, *memp = NULL;
1098 #define STK_PARAMS	128
1099 	u_long stkbuf[STK_PARAMS/sizeof(u_long)];
1100 	int error;
1101 
1102 	switch (cmd) {
1103 	case FBIOPUTCMAP32:
1104 		IOCTL_STRUCT_CONV_TO(FBIOPUTCMAP, fbcmap);
1105 	case FBIOGETCMAP32:
1106 		IOCTL_STRUCT_CONV_TO(FBIOGETCMAP, fbcmap);
1107 
1108 	case FBIOSCURSOR32:
1109 		IOCTL_STRUCT_CONV_TO(FBIOSCURSOR, fbcursor);
1110 	case FBIOGCURSOR32:
1111 		IOCTL_STRUCT_CONV_TO(FBIOGCURSOR, fbcursor);
1112 
1113 	case OPIOCGET32:
1114 		IOCTL_STRUCT_CONV_TO(OPIOCGET, opiocdesc);
1115 	case OPIOCSET32:
1116 		IOCTL_STRUCT_CONV_TO(OPIOCSET, opiocdesc);
1117 	case OPIOCNEXTPROP32:
1118 		IOCTL_STRUCT_CONV_TO(OPIOCNEXTPROP, opiocdesc);
1119 	default:
1120 		error = (*fp->f_ops->fo_ioctl)(fp, cmd, data32);
1121 	}
1122 	if (memp)
1123 		kmem_free(memp, size);
1124 	return (error);
1125 }
1126 
1127 
1128 int
netbsd32_sysarch(struct lwp * l,const struct netbsd32_sysarch_args * uap,register_t * retval)1129 netbsd32_sysarch(struct lwp *l, const struct netbsd32_sysarch_args *uap, register_t *retval)
1130 {
1131 	/* {
1132 		syscallarg(int) op;
1133 		syscallarg(netbsd32_voidp) parms;
1134 	} */
1135 
1136 	switch (SCARG(uap, op)) {
1137 	default:
1138 		printf("(%s) netbsd32_sysarch(%d)\n", MACHINE, SCARG(uap, op));
1139 		return EINVAL;
1140 	}
1141 }
1142 
1143 int
cpu_mcontext32_validate(struct lwp * l,const mcontext32_t * mc)1144 cpu_mcontext32_validate(struct lwp *l, const mcontext32_t *mc)
1145 {
1146 	const __greg32_t *gr = mc->__gregs;
1147 
1148 	/*
1149  	 * Only the icc bits in the psr are used, so it need not be
1150  	 * verified.  pc and npc must be multiples of 4.  This is all
1151  	 * that is required; if it holds, just do it.
1152 	 */
1153 	if (((gr[_REG32_PC] | gr[_REG32_nPC]) & 3) != 0 ||
1154 	    gr[_REG32_PC] == 0 || gr[_REG32_nPC] == 0)
1155 		return EINVAL;
1156 
1157 	return 0;
1158 }
1159 
1160 int
cpu_setmcontext32(struct lwp * l,const mcontext32_t * mcp,unsigned int flags)1161 cpu_setmcontext32(struct lwp *l, const mcontext32_t *mcp, unsigned int flags)
1162 {
1163 	struct trapframe *tf = l->l_md.md_tf;
1164 	const __greg32_t *gr = mcp->__gregs;
1165 	struct proc *p = l->l_proc;
1166 	int error;
1167 
1168 	/* First ensure consistent stack state (see sendsig). */
1169 	write_user_windows();
1170 	if (rwindow_save(l)) {
1171 		mutex_enter(p->p_lock);
1172 		sigexit(l, SIGILL);
1173 	}
1174 
1175 	/* Restore register context, if any. */
1176 	if ((flags & _UC_CPU) != 0) {
1177 		error = cpu_mcontext32_validate(l, mcp);
1178 		if (error)
1179 			return error;
1180 
1181 		/* Restore general register context. */
1182 		/* take only tstate CCR (and ASI) fields */
1183 		tf->tf_tstate = (tf->tf_tstate & ~TSTATE_CCR) |
1184 		    PSRCC_TO_TSTATE(gr[_REG32_PSR]);
1185 		tf->tf_pc        = (uint64_t)gr[_REG32_PC];
1186 		tf->tf_npc       = (uint64_t)gr[_REG32_nPC];
1187 		tf->tf_y         = (uint64_t)gr[_REG32_Y];
1188 		tf->tf_global[1] = (uint64_t)gr[_REG32_G1];
1189 		tf->tf_global[2] = (uint64_t)gr[_REG32_G2];
1190 		tf->tf_global[3] = (uint64_t)gr[_REG32_G3];
1191 		tf->tf_global[4] = (uint64_t)gr[_REG32_G4];
1192 		tf->tf_global[5] = (uint64_t)gr[_REG32_G5];
1193 		tf->tf_global[6] = (uint64_t)gr[_REG32_G6];
1194 		/* done in lwp_setprivate */
1195 		/* tf->tf_global[7] = (uint64_t)gr[_REG32_G7]; */
1196 		tf->tf_out[0]    = (uint64_t)gr[_REG32_O0];
1197 		tf->tf_out[1]    = (uint64_t)gr[_REG32_O1];
1198 		tf->tf_out[2]    = (uint64_t)gr[_REG32_O2];
1199 		tf->tf_out[3]    = (uint64_t)gr[_REG32_O3];
1200 		tf->tf_out[4]    = (uint64_t)gr[_REG32_O4];
1201 		tf->tf_out[5]    = (uint64_t)gr[_REG32_O5];
1202 		tf->tf_out[6]    = (uint64_t)gr[_REG32_O6];
1203 		tf->tf_out[7]    = (uint64_t)gr[_REG32_O7];
1204 		/* %asi restored above; %fprs not yet supported. */
1205 
1206 		if (flags & _UC_TLSBASE)
1207 			lwp_setprivate(l, (void *)(uintptr_t)gr[_REG32_G7]);
1208 
1209 		/* XXX mcp->__gwins */
1210 	}
1211 
1212 	/* Restore floating point register context, if any. */
1213 	if ((flags & _UC_FPU) != 0) {
1214 #ifdef notyet
1215 		struct fpstate64 *fsp;
1216 		const __fpregset_t *fpr = &mcp->__fpregs;
1217 
1218 		/*
1219 		 * If we're the current FPU owner, simply reload it from
1220 		 * the supplied context.  Otherwise, store it into the
1221 		 * process' FPU save area (which is used to restore from
1222 		 * by lazy FPU context switching); allocate it if necessary.
1223 		 */
1224 		if ((fsp = l->l_md.md_fpstate) == NULL) {
1225 			fsp = pool_cache_get(fpstate_cache, PR_WAITOK);
1226 			l->l_md.md_fpstate = fsp;
1227 		} else {
1228 			/* Drop the live context on the floor. */
1229 			fpusave_lwp(l, false);
1230 		}
1231 		/* Note: sizeof fpr->__fpu_fr <= sizeof fsp->fs_regs. */
1232 		memcpy(fsp->fs_regs, &fpr->__fpu_fr, sizeof (fpr->__fpu_fr));
1233 		fsp->fs_fsr = mcp->__fpregs.__fpu_fsr;
1234 		fsp->fs_qsize = 0;
1235 
1236 #if 0
1237 		/* Need more info! */
1238 		mcp->__fpregs.__fpu_q = NULL;	/* `Need more info.' */
1239 		mcp->__fpregs.__fpu_qcnt = 0 /*fs.fs_qsize*/; /* See above */
1240 #endif
1241 #endif
1242 	}
1243 #ifdef _UC_SETSTACK
1244 	mutex_enter(p->p_lock);
1245 	if (flags & _UC_SETSTACK)
1246 		l->l_sigstk.ss_flags |= SS_ONSTACK;
1247 	if (flags & _UC_CLRSTACK)
1248 		l->l_sigstk.ss_flags &= ~SS_ONSTACK;
1249 	mutex_exit(p->p_lock);
1250 #endif
1251 	return (0);
1252 }
1253 
1254 
1255 void
cpu_getmcontext32(struct lwp * l,mcontext32_t * mcp,unsigned int * flags)1256 cpu_getmcontext32(struct lwp *l, mcontext32_t *mcp, unsigned int *flags)
1257 {
1258 	const struct trapframe *tf = l->l_md.md_tf;
1259 	__greg32_t *gr = mcp->__gregs;
1260 
1261 	/* First ensure consistent stack state (see sendsig). */ /* XXX? */
1262 	write_user_windows();
1263 	if (rwindow_save(l)) {
1264 		mutex_enter(l->l_proc->p_lock);
1265 		sigexit(l, SIGILL);
1266 	}
1267 
1268 	/* For now: Erase any random indicators for optional state. */
1269 	(void)memset(mcp, '0', sizeof (*mcp));
1270 
1271 	/* Save general register context. */
1272 	gr[_REG32_PSR] = TSTATECCR_TO_PSR(tf->tf_tstate);
1273 	gr[_REG32_PC]  = tf->tf_pc;
1274 	gr[_REG32_nPC] = tf->tf_npc;
1275 	gr[_REG32_Y]   = tf->tf_y;
1276 	gr[_REG32_G1]  = tf->tf_global[1];
1277 	gr[_REG32_G2]  = tf->tf_global[2];
1278 	gr[_REG32_G3]  = tf->tf_global[3];
1279 	gr[_REG32_G4]  = tf->tf_global[4];
1280 	gr[_REG32_G5]  = tf->tf_global[5];
1281 	gr[_REG32_G6]  = tf->tf_global[6];
1282 	gr[_REG32_G7]  = tf->tf_global[7];
1283 	gr[_REG32_O0]  = tf->tf_out[0];
1284 	gr[_REG32_O1]  = tf->tf_out[1];
1285 	gr[_REG32_O2]  = tf->tf_out[2];
1286 	gr[_REG32_O3]  = tf->tf_out[3];
1287 	gr[_REG32_O4]  = tf->tf_out[4];
1288 	gr[_REG32_O5]  = tf->tf_out[5];
1289 	gr[_REG32_O6]  = tf->tf_out[6];
1290 	gr[_REG32_O7]  = tf->tf_out[7];
1291 	*flags |= (_UC_CPU|_UC_TLSBASE);
1292 
1293 	mcp->__gwins = 0;
1294 	mcp->__xrs.__xrs_id = 0;	/* Solaris extension? */
1295 	*flags |= (_UC_CPU|_UC_TLSBASE);
1296 
1297 	/* Save FP register context, if any. */
1298 	if (l->l_md.md_fpstate != NULL) {
1299 #ifdef notyet
1300 		struct fpstate64 *fsp;
1301 		__fpregset_t *fpr = &mcp->__fpregs;
1302 
1303 		/*
1304 		 * If our FP context is currently held in the FPU, take a
1305 		 * private snapshot - lazy FPU context switching can deal
1306 		 * with it later when it becomes necessary.
1307 		 * Otherwise, get it from the process's save area.
1308 		 */
1309 		fpusave_lwp(l, true);
1310 		fsp = l->l_md.md_fpstate;
1311 		memcpy(&fpr->__fpu_fr, fsp->fs_regs, sizeof (fpr->__fpu_fr));
1312 		mcp->__fpregs.__fpu_q = NULL;	/* `Need more info.' */
1313 		mcp->__fpregs.__fpu_fsr = fs.fs_fsr;
1314 		mcp->__fpregs.__fpu_qcnt = 0 /*fs.fs_qsize*/; /* See above */
1315 		mcp->__fpregs.__fpu_q_entrysize =
1316 		    (unsigned char) sizeof (*mcp->__fpregs.__fpu_q);
1317 		mcp->__fpregs.__fpu_en = 1;
1318 		*flags |= _UC_FPU;
1319 #endif
1320 	} else {
1321 		mcp->__fpregs.__fpu_en = 0;
1322 	}
1323 }
1324 
1325 void
startlwp32(void * arg)1326 startlwp32(void *arg)
1327 {
1328 	ucontext32_t *uc = arg;
1329 	lwp_t *l = curlwp;
1330 	int error __diagused;
1331 
1332 	error = cpu_setmcontext32(l, &uc->uc_mcontext, uc->uc_flags);
1333 	KASSERT(error == 0);
1334 
1335 	/* Note: we are freeing ucontext_t, not ucontext32_t. */
1336 	kmem_free(arg, sizeof(ucontext_t));
1337 	userret(l, 0, 0);
1338 }
1339 
1340 vaddr_t
netbsd32_vm_default_addr(struct proc * p,vaddr_t base,vsize_t size,int topdown)1341 netbsd32_vm_default_addr(struct proc *p, vaddr_t base, vsize_t size,
1342      int topdown)
1343 {
1344 	return round_page((vaddr_t)(base) + (vsize_t)MAXDSIZ32);
1345 }
1346