1 
2 /*
3  * Copyright (c) 1998, 2001 Matthew R. Green
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
22  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29 
30 #ifdef _KERNEL_OPT
31 #include "opt_compat_netbsd.h"
32 #endif
33 
34 #include <sys/param.h>
35 #include <sys/exec.h>
36 #include <sys/malloc.h>
37 #include <sys/filedesc.h>
38 #include <sys/file.h>
39 #include <sys/proc.h>
40 #include <sys/signalvar.h>
41 #include <sys/systm.h>
42 #include <sys/user.h>
43 #include <sys/core.h>
44 #include <sys/mount.h>
45 #include <sys/buf.h>
46 #include <sys/vnode.h>
47 #include <sys/select.h>
48 #include <sys/ioctl.h>
49 
50 #include <dev/sun/event_var.h>
51 
52 #include <net/if.h>
53 #include <net/route.h>
54 
55 #include <netinet/in.h>
56 #include <netinet/in_var.h>
57 #include <netinet/igmp.h>
58 #include <netinet/igmp_var.h>
59 #include <netinet/ip_mroute.h>
60 
61 #include <compat/netbsd32/netbsd32.h>
62 #include <compat/netbsd32/netbsd32_ioctl.h>
63 #include <compat/netbsd32/netbsd32_syscallargs.h>
64 
65 #include <machine/frame.h>
66 #include <machine/reg.h>
67 #include <machine/vmparam.h>
68 #include <machine/vuid_event.h>
69 #include <machine/netbsd32_machdep.h>
70 
71 /* Provide a the name of the architecture we're emulating */
72 char	machine_arch32[] = "sparc";
73 
74 static int ev_out32 __P((struct firm_event *, int, struct uio *));
75 
76 /*
77  * Set up registers on exec.
78  *
79  * XXX this entire mess must be fixed
80  */
81 /* ARGSUSED */
82 void
83 netbsd32_setregs(p, pack, stack)
84 	struct proc *p;
85 	struct exec_package *pack;
86 	u_long stack; /* XXX */
87 {
88 	register struct trapframe64 *tf = p->p_md.md_tf;
89 	register struct fpstate64 *fs;
90 	register int64_t tstate;
91 
92 	/* Don't allow misaligned code by default */
93 	p->p_md.md_flags &= ~MDP_FIXALIGN;
94 
95 	/* Mark this as a 32-bit emulation */
96 	p->p_flag |= P_32;
97 
98 	/* Setup the ev_out32 hook */
99 	if (ev_out32_hook == NULL)
100 		ev_out32_hook = ev_out32;
101 
102 	/*
103 	 * Set the registers to 0 except for:
104 	 *	%o6: stack pointer, built in exec())
105 	 *	%tstate: (retain icc and xcc and cwp bits)
106 	 *	%g1: address of p->p_psstr (used by crt0)
107 	 *	%tpc,%tnpc: entry point of program
108 	 */
109 	tstate = ((PSTATE_USER32)<<TSTATE_PSTATE_SHIFT)
110 		| (tf->tf_tstate & TSTATE_CWP);
111 	if ((fs = p->p_md.md_fpstate) != NULL) {
112 		/*
113 		 * We hold an FPU state.  If we own *the* FPU chip state
114 		 * we must get rid of it, and the only way to do that is
115 		 * to save it.  In any case, get rid of our FPU state.
116 		 */
117 		if (p == fpproc) {
118 			savefpstate(fs);
119 			fpproc = NULL;
120 		}
121 		free((void *)fs, M_SUBPROC);
122 		p->p_md.md_fpstate = NULL;
123 	}
124 	bzero((caddr_t)tf, sizeof *tf);
125 	tf->tf_tstate = tstate;
126 	tf->tf_global[1] = (u_int)(u_long)p->p_psstr;
127 	tf->tf_pc = pack->ep_entry & ~3;
128 	tf->tf_npc = tf->tf_pc + 4;
129 
130 	stack -= sizeof(struct rwindow32);
131 	tf->tf_out[6] = stack;
132 	tf->tf_out[7] = NULL;
133 }
134 
135 /*
136  * NB: since this is a 32-bit address world, sf_scp and sf_sc
137  *	can't be a pointer since those are 64-bits wide.
138  */
139 struct sparc32_sigframe {
140 	int	sf_signo;		/* signal number */
141 	int	sf_code;		/* code */
142 	u_int	sf_scp;			/* SunOS user addr of sigcontext */
143 	int	sf_addr;		/* SunOS compat, always 0 for now */
144 	struct	netbsd32_sigcontext sf_sc;	/* actual sigcontext */
145 };
146 
147 #undef DEBUG
148 #ifdef DEBUG
149 extern int sigdebug;
150 #endif
151 
152 void
153 netbsd32_sendsig(sig, mask, code)
154 	int sig;
155 	sigset_t *mask;
156 	u_long code;
157 {
158 	register struct proc *p = curproc;
159 	register struct sparc32_sigframe *fp;
160 	register struct trapframe64 *tf;
161 	register int addr, onstack;
162 	struct rwindow32 *kwin, *oldsp, *newsp;
163 	sig_t catcher = SIGACTION(p, sig).sa_handler;
164 	struct sparc32_sigframe sf;
165 	extern char netbsd32_sigcode[], netbsd32_esigcode[];
166 #define	szsigcode	(netbsd32_esigcode - netbsd32_sigcode)
167 
168 	tf = p->p_md.md_tf;
169 	/* Need to attempt to zero extend this 32-bit pointer */
170 	oldsp = (struct rwindow32 *)(u_long)(u_int)tf->tf_out[6];
171 	/* Do we need to jump onto the signal stack? */
172 	onstack =
173 	    (p->p_sigctx.ps_sigstk.ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 &&
174 	    (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0;
175 	if (onstack) {
176 		fp = (struct sparc32_sigframe *)((char *)p->p_sigctx.ps_sigstk.ss_sp +
177 					p->p_sigctx.ps_sigstk.ss_size);
178 		p->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK;
179 	} else
180 		fp = (struct sparc32_sigframe *)oldsp;
181 	fp = (struct sparc32_sigframe *)((u_long)(fp - 1) & ~7);
182 
183 #ifdef DEBUG
184 	sigpid = p->p_pid;
185 	if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) {
186 		printf("sendsig: %s[%d] sig %d newusp %p scp %p oldsp %p\n",
187 		    p->p_comm, p->p_pid, sig, fp, &fp->sf_sc, oldsp);
188 		if (sigdebug & SDB_DDB) Debugger();
189 	}
190 #endif
191 	/*
192 	 * Now set up the signal frame.  We build it in kernel space
193 	 * and then copy it out.  We probably ought to just build it
194 	 * directly in user space....
195 	 */
196 	sf.sf_signo = sig;
197 	sf.sf_code = (u_int)code;
198 #if defined(COMPAT_SUNOS) || defined(LKM)
199 	sf.sf_scp = (u_long)&fp->sf_sc;
200 #endif
201 	sf.sf_addr = 0;			/* XXX */
202 
203 	/*
204 	 * Build the signal context to be used by sigreturn.
205 	 */
206 	sf.sf_sc.sc_onstack = onstack;
207 	sf.sf_sc.sc_mask = *mask;
208 	sf.sf_sc.sc_sp = (u_long)oldsp;
209 	sf.sf_sc.sc_pc = tf->tf_pc;
210 	sf.sf_sc.sc_npc = tf->tf_npc;
211 	sf.sf_sc.sc_psr = TSTATECCR_TO_PSR(tf->tf_tstate); /* XXX */
212 	sf.sf_sc.sc_g1 = tf->tf_global[1];
213 	sf.sf_sc.sc_o0 = tf->tf_out[0];
214 
215 	/*
216 	 * Put the stack in a consistent state before we whack away
217 	 * at it.  Note that write_user_windows may just dump the
218 	 * registers into the pcb; we need them in the process's memory.
219 	 * We also need to make sure that when we start the signal handler,
220 	 * its %i6 (%fp), which is loaded from the newly allocated stack area,
221 	 * joins seamlessly with the frame it was in when the signal occurred,
222 	 * so that the debugger and _longjmp code can back up through it.
223 	 */
224 	newsp = (struct rwindow32 *)((long)fp - sizeof(struct rwindow32));
225 	write_user_windows();
226 #ifdef DEBUG
227 	if ((sigdebug & SDB_KSTACK))
228 	    printf("sendsig: saving sf to %p, setting stack pointer %p to %p\n",
229 		   fp, &(((struct rwindow32 *)newsp)->rw_in[6]), oldsp);
230 #endif
231 	kwin = (struct rwindow32 *)(((caddr_t)tf)-CCFSZ);
232 	if (rwindow_save(p) ||
233 	    copyout((caddr_t)&sf, (caddr_t)fp, sizeof sf) ||
234 	    suword(&(((struct rwindow32 *)newsp)->rw_in[6]), (u_long)oldsp)) {
235 		/*
236 		 * Process has trashed its stack; give it an illegal
237 		 * instruction to halt it in its tracks.
238 		 */
239 #ifdef DEBUG
240 		if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
241 			printf("sendsig: window save or copyout error\n");
242 		printf("sendsig: stack was trashed trying to send sig %d, sending SIGILL\n", sig);
243 		if (sigdebug & SDB_DDB) Debugger();
244 #endif
245 		sigexit(p, SIGILL);
246 		/* NOTREACHED */
247 	}
248 
249 #ifdef DEBUG
250 	if (sigdebug & SDB_FOLLOW) {
251 		printf("sendsig: %s[%d] sig %d scp %p\n",
252 		       p->p_comm, p->p_pid, sig, &fp->sf_sc);
253 	}
254 #endif
255 	/*
256 	 * Arrange to continue execution at the code copied out in exec().
257 	 * It needs the function to call in %g1, and a new stack pointer.
258 	 */
259 	addr = (long)p->p_psstr - szsigcode;
260 	tf->tf_global[1] = (long)catcher;
261 	tf->tf_pc = addr;
262 	tf->tf_npc = addr + 4;
263 	tf->tf_out[6] = (u_int64_t)(u_int)(u_long)newsp;
264 
265 	/* Remember that we're now on the signal stack. */
266 	if (onstack)
267 		p->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK;
268 
269 #ifdef DEBUG
270 	if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) {
271 		printf("sendsig: about to return to catcher %p thru %p\n",
272 		       catcher, addr);
273 		if (sigdebug & SDB_DDB) Debugger();
274 	}
275 #endif
276 }
277 
278 #undef DEBUG
279 
280 #ifdef COMPAT_13
281 int
282 compat_13_netbsd32_sigreturn(p, v, retval)
283 	struct proc *p;
284 	void *v;
285 	register_t *retval;
286 {
287 	struct compat_13_netbsd32_sigreturn_args /* {
288 		syscallarg(struct netbsd32_sigcontext13 *) sigcntxp;
289 	} */ *uap = v;
290 	struct netbsd32_sigcontext13 *scp;
291 	struct netbsd32_sigcontext13 sc;
292 	register struct trapframe64 *tf;
293 	sigset_t mask;
294 
295 	/* First ensure consistent stack state (see sendsig). */
296 	write_user_windows();
297 	if (rwindow_save(p)) {
298 #ifdef DEBUG
299 		printf("compat_13_netbsd32_sigreturn: rwindow_save(%p) failed, sending SIGILL\n", p);
300 		Debugger();
301 #endif
302 		sigexit(p, SIGILL);
303 	}
304 #ifdef DEBUG
305 	if (sigdebug & SDB_FOLLOW) {
306 		printf("compat_13_netbsd32_sigreturn: %s[%d], sigcntxp %p\n",
307 		    p->p_comm, p->p_pid, SCARG(uap, sigcntxp));
308 		if (sigdebug & SDB_DDB) Debugger();
309 	}
310 #endif
311 	scp = (struct netbsd32_sigcontext13 *)(u_long)SCARG(uap, sigcntxp);
312  	if ((vaddr_t)scp & 3 || (copyin((caddr_t)scp, &sc, sizeof sc) != 0))
313 	{
314 #ifdef DEBUG
315 		printf("compat_13_netbsd32_sigreturn: copyin failed\n");
316 		Debugger();
317 #endif
318 		return (EINVAL);
319 	}
320 	scp = &sc;
321 
322 	tf = p->p_md.md_tf;
323 	/*
324 	 * Only the icc bits in the psr are used, so it need not be
325 	 * verified.  pc and npc must be multiples of 4.  This is all
326 	 * that is required; if it holds, just do it.
327 	 */
328 	if (((sc.sc_pc | sc.sc_npc) & 3) != 0)
329 #ifdef DEBUG
330 	{
331 		printf("compat_13_netbsd32_sigreturn: pc %p or npc %p invalid\n", sc.sc_pc, sc.sc_npc);
332 		Debugger();
333 		return (EINVAL);
334 	}
335 #else
336 		return (EINVAL);
337 #endif
338 	/* take only psr ICC field */
339 	tf->tf_tstate = (int64_t)(tf->tf_tstate & ~TSTATE_CCR) | PSRCC_TO_TSTATE(sc.sc_psr);
340 	tf->tf_pc = (int64_t)sc.sc_pc;
341 	tf->tf_npc = (int64_t)sc.sc_npc;
342 	tf->tf_global[1] = (int64_t)sc.sc_g1;
343 	tf->tf_out[0] = (int64_t)sc.sc_o0;
344 	tf->tf_out[6] = (int64_t)sc.sc_sp;
345 #ifdef DEBUG
346 	if (sigdebug & SDB_FOLLOW) {
347 		printf("compat_13_netbsd32_sys_sigreturn: return trapframe pc=%p sp=%p tstate=%x\n",
348 		       (int)tf->tf_pc, (int)tf->tf_out[6], (int)tf->tf_tstate);
349 		if (sigdebug & SDB_DDB) Debugger();
350 	}
351 #endif
352 	if (scp->sc_onstack & SS_ONSTACK)
353 		p->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK;
354 	else
355 		p->p_sigctx.ps_sigstk.ss_flags &= ~SS_ONSTACK;
356 
357 	/* Restore signal mask */
358 	native_sigset13_to_sigset(&scp->sc_mask, &mask);
359 	(void) sigprocmask1(p, SIG_SETMASK, &mask, 0);
360 
361 	return (EJUSTRETURN);
362 }
363 #endif
364 
365 /*
366  * System call to cleanup state after a signal
367  * has been taken.  Reset signal mask and
368  * stack state from context left by sendsig (above),
369  * and return to the given trap frame (if there is one).
370  * Check carefully to make sure that the user has not
371  * modified the state to gain improper privileges or to cause
372  * a machine fault.
373  */
374 /* ARGSUSED */
375 int
376 netbsd32___sigreturn14(p, v, retval)
377 	register struct proc *p;
378 	void *v;
379 	register_t *retval;
380 {
381 	struct netbsd32___sigreturn14_args /* {
382 		syscallarg(struct sigcontext *) sigcntxp;
383 	} */ *uap = v;
384 	struct netbsd32_sigcontext sc, *scp;
385 	register struct trapframe64 *tf;
386 
387 	/* First ensure consistent stack state (see sendsig). */
388 	write_user_windows();
389 	if (rwindow_save(p)) {
390 #ifdef DEBUG
391 		printf("netbsd32_sigreturn14: rwindow_save(%p) failed, sending SIGILL\n", p);
392 		Debugger();
393 #endif
394 		sigexit(p, SIGILL);
395 	}
396 #ifdef DEBUG
397 	if (sigdebug & SDB_FOLLOW) {
398 		printf("netbsd32_sigreturn14: %s[%d], sigcntxp %p\n",
399 		    p->p_comm, p->p_pid, SCARG(uap, sigcntxp));
400 		if (sigdebug & SDB_DDB) Debugger();
401 	}
402 #endif
403 	scp = (struct netbsd32_sigcontext *)(u_long)SCARG(uap, sigcntxp);
404  	if ((vaddr_t)scp & 3 || (copyin((caddr_t)scp, &sc, sizeof sc) != 0))
405 	{
406 #ifdef DEBUG
407 		printf("netbsd32_sigreturn14: copyin failed: scp=%p\n", scp);
408 		Debugger();
409 #endif
410 		return (EINVAL);
411 	}
412 	scp = &sc;
413 
414 	tf = p->p_md.md_tf;
415 	/*
416 	 * Only the icc bits in the psr are used, so it need not be
417 	 * verified.  pc and npc must be multiples of 4.  This is all
418 	 * that is required; if it holds, just do it.
419 	 */
420 	if (((sc.sc_pc | sc.sc_npc) & 3) != 0 || (sc.sc_pc == 0) || (sc.sc_npc == 0))
421 #ifdef DEBUG
422 	{
423 		printf("netbsd32_sigreturn14: pc %p or npc %p invalid\n", sc.sc_pc, sc.sc_npc);
424 		Debugger();
425 		return (EINVAL);
426 	}
427 #else
428 		return (EINVAL);
429 #endif
430 	/* take only psr ICC field */
431 	tf->tf_tstate = (int64_t)(tf->tf_tstate & ~TSTATE_CCR) | PSRCC_TO_TSTATE(sc.sc_psr);
432 	tf->tf_pc = (int64_t)sc.sc_pc;
433 	tf->tf_npc = (int64_t)sc.sc_npc;
434 	tf->tf_global[1] = (int64_t)sc.sc_g1;
435 	tf->tf_out[0] = (int64_t)sc.sc_o0;
436 	tf->tf_out[6] = (int64_t)sc.sc_sp;
437 #ifdef DEBUG
438 	if (sigdebug & SDB_FOLLOW) {
439 		printf("netbsd32_sigreturn14: return trapframe pc=%p sp=%p tstate=%llx\n",
440 		       (vaddr_t)tf->tf_pc, (vaddr_t)tf->tf_out[6], tf->tf_tstate);
441 		if (sigdebug & SDB_DDB) Debugger();
442 	}
443 #endif
444 
445 	/* Restore signal stack. */
446 	if (sc.sc_onstack & SS_ONSTACK)
447 		p->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK;
448 	else
449 		p->p_sigctx.ps_sigstk.ss_flags &= ~SS_ONSTACK;
450 
451 	/* Restore signal mask. */
452 	(void) sigprocmask1(p, SIG_SETMASK, &sc.sc_mask, 0);
453 
454 	return (EJUSTRETURN);
455 }
456 
457 #if 0
458 /* Unfortunately we need to convert v9 trapframe to v8 regs */
459 int
460 netbsd32_process_read_regs(p, regs)
461 	struct proc *p;
462 	struct reg *regs;
463 {
464 	struct reg32* regp = (struct reg32*)regs;
465 	struct trapframe64* tf = p->p_md.md_tf;
466 	int i;
467 
468 	/*
469 	 * Um, we should only do this conversion for 32-bit emulation
470 	 * or when running 32-bit mode.  We really need to pass in a
471 	 * 32-bit emulation flag!
472 	 */
473 
474 	regp->r_psr = TSTATECCR_TO_PSR(tf->tf_tstate);
475 	regp->r_pc = tf->tf_pc;
476 	regp->r_npc = tf->tf_npc;
477 	regp->r_y = tf->tf_y;
478 	for (i = 0; i < 8; i++) {
479 		regp->r_global[i] = tf->tf_global[i];
480 		regp->r_out[i] = tf->tf_out[i];
481 	}
482 	/* We should also write out the ins and locals.  See signal stuff */
483 	return (0);
484 }
485 
486 int
487 netbsd32_process_write_regs(p, regs)
488 	struct proc *p;
489 	struct reg *regs;
490 {
491 	struct reg32* regp = (struct reg32*)regs;
492 	struct trapframe64* tf = p->p_md.md_tf;
493 	int i;
494 
495 	tf->tf_pc = regp->r_pc;
496 	tf->tf_npc = regp->r_npc;
497 	tf->tf_y = regp->r_pc;
498 	for (i = 0; i < 8; i++) {
499 		tf->tf_global[i] = regp->r_global[i];
500 		tf->tf_out[i] = regp->r_out[i];
501 	}
502 	/* We should also read in the ins and locals.  See signal stuff */
503 	tf->tf_tstate = (int64_t)(tf->tf_tstate & ~TSTATE_CCR) | PSRCC_TO_TSTATE(regp->r_psr);
504 	return (0);
505 }
506 
507 int
508 netbsd32_process_read_fpregs(p, regs)
509 struct proc	*p;
510 struct fpreg	*regs;
511 {
512 	extern struct fpstate64	initfpstate;
513 	struct fpstate64	*statep = &initfpstate;
514 	struct fpreg32		*regp = (struct fpreg32 *)regs;
515 	int i;
516 
517 	/* NOTE: struct fpreg == struct fpstate */
518 	if (p->p_md.md_fpstate)
519 		statep = p->p_md.md_fpstate;
520 	for (i=0; i<32; i++)
521 		regp->fr_regs[i] = statep->fs_regs[i];
522 	regp->fr_fsr = statep->fs_fsr;
523 	regp->fr_qsize = statep->fs_qsize;
524 	for (i=0; i<statep->fs_qsize; i++)
525 		regp->fr_queue[i] = statep->fs_queue[i];
526 
527 	return 0;
528 }
529 
530 int
531 netbsd32_process_write_fpregs(p, regs)
532 struct proc	*p;
533 struct fpreg	*regs;
534 {
535 	extern struct fpstate	initfpstate;
536 	struct fpstate64	*statep = &initfpstate;
537 	struct fpreg32		*regp = (struct fpreg32 *)regs;
538 	int i;
539 
540 	/* NOTE: struct fpreg == struct fpstate */
541 	if (p->p_md.md_fpstate)
542 		statep = p->p_md.md_fpstate;
543 	for (i=0; i<32; i++)
544 		statep->fs_regs[i] = regp->fr_regs[i];
545 	statep->fs_fsr = regp->fr_fsr;
546 	statep->fs_qsize = regp->fr_qsize;
547 	for (i=0; i<regp->fr_qsize; i++)
548 		statep->fs_queue[i] = regp->fr_queue[i];
549 
550 	return 0;
551 }
552 #endif
553 
554 /*
555  * 32-bit version of cpu_coredump.
556  */
557 int
558 cpu_coredump32(p, vp, cred, chdr)
559 	struct proc *p;
560 	struct vnode *vp;
561 	struct ucred *cred;
562 	struct core32 *chdr;
563 {
564 	int i, error;
565 	struct md_coredump32 md_core;
566 	struct coreseg32 cseg;
567 
568 	CORE_SETMAGIC(*chdr, COREMAGIC, MID_MACHINE, 0);
569 	chdr->c_hdrsize = ALIGN(sizeof(*chdr));
570 	chdr->c_seghdrsize = ALIGN(sizeof(cseg));
571 	chdr->c_cpusize = sizeof(md_core);
572 
573 	/* Fake a v8 trapframe */
574 	md_core.md_tf.tf_psr = TSTATECCR_TO_PSR(p->p_md.md_tf->tf_tstate);
575 	md_core.md_tf.tf_pc = p->p_md.md_tf->tf_pc;
576 	md_core.md_tf.tf_npc = p->p_md.md_tf->tf_npc;
577 	md_core.md_tf.tf_y = p->p_md.md_tf->tf_y;
578 	for (i=0; i<8; i++) {
579 		md_core.md_tf.tf_global[i] = p->p_md.md_tf->tf_global[i];
580 		md_core.md_tf.tf_out[i] = p->p_md.md_tf->tf_out[i];
581 	}
582 
583 	if (p->p_md.md_fpstate) {
584 		if (p == fpproc) {
585 			savefpstate(p->p_md.md_fpstate);
586 			fpproc = NULL;
587 		}
588 		/* Copy individual fields */
589 		for (i=0; i<32; i++)
590 			md_core.md_fpstate.fs_regs[i] =
591 				p->p_md.md_fpstate->fs_regs[i];
592 		md_core.md_fpstate.fs_fsr = p->p_md.md_fpstate->fs_fsr;
593 		i = md_core.md_fpstate.fs_qsize = p->p_md.md_fpstate->fs_qsize;
594 		/* Should always be zero */
595 		while (i--)
596 			md_core.md_fpstate.fs_queue[i] =
597 				p->p_md.md_fpstate->fs_queue[i];
598 	} else
599 		bzero((caddr_t)&md_core.md_fpstate,
600 		      sizeof(md_core.md_fpstate));
601 
602 	CORE_SETMAGIC(cseg, CORESEGMAGIC, MID_MACHINE, CORE_CPU);
603 	cseg.c_addr = 0;
604 	cseg.c_size = chdr->c_cpusize;
605 	error = vn_rdwr(UIO_WRITE, vp, (caddr_t)&cseg, chdr->c_seghdrsize,
606 	    (off_t)chdr->c_hdrsize, UIO_SYSSPACE,
607 	    IO_NODELOCKED|IO_UNIT, cred, NULL, p);
608 	if (error)
609 		return error;
610 
611 	error = vn_rdwr(UIO_WRITE, vp, (caddr_t)&md_core, sizeof(md_core),
612 	    (off_t)(chdr->c_hdrsize + chdr->c_seghdrsize), UIO_SYSSPACE,
613 	    IO_NODELOCKED|IO_UNIT, cred, NULL, p);
614 	if (!error)
615 		chdr->c_nseg++;
616 
617 	return error;
618 }
619 
620 /*
621  * Write out a series of 32-bit firm_events.
622  */
623 int
624 ev_out32(e, n, uio)
625 	struct firm_event *e;
626 	int n;
627 	struct uio *uio;
628 {
629 	struct firm_event32 e32;
630 	int error = 0;
631 
632 	while (n-- && error == 0) {
633 		e32.id = e->id;
634 		e32.value = e->value;
635 		e32.time.tv_sec = e->time.tv_sec;
636 		e32.time.tv_usec = e->time.tv_usec;
637 		error = uiomove((caddr_t)&e32, sizeof(e32), uio);
638 		e++;
639 	}
640 	return (error);
641 }
642 
643 /*
644  * ioctl code
645  */
646 
647 #include <dev/sun/fbio.h>
648 #include <machine/openpromio.h>
649 
650 /* from arch/sparc/include/fbio.h */
651 #if 0
652 /* unused */
653 #define	FBIOGINFO	_IOR('F', 2, struct fbinfo)
654 #endif
655 
656 struct netbsd32_fbcmap {
657 	int	index;		/* first element (0 origin) */
658 	int	count;		/* number of elements */
659 	netbsd32_u_charp	red;		/* red color map elements */
660 	netbsd32_u_charp	green;		/* green color map elements */
661 	netbsd32_u_charp	blue;		/* blue color map elements */
662 };
663 #if 1
664 #define	FBIOPUTCMAP32	_IOW('F', 3, struct netbsd32_fbcmap)
665 #define	FBIOGETCMAP32	_IOW('F', 4, struct netbsd32_fbcmap)
666 #endif
667 
668 struct netbsd32_fbcursor {
669 	short set;		/* what to set */
670 	short enable;		/* enable/disable cursor */
671 	struct fbcurpos pos;	/* cursor's position */
672 	struct fbcurpos hot;	/* cursor's hot spot */
673 	struct netbsd32_fbcmap cmap;	/* color map info */
674 	struct fbcurpos size;	/* cursor's bit map size */
675 	netbsd32_charp image;	/* cursor's image bits */
676 	netbsd32_charp mask;	/* cursor's mask bits */
677 };
678 #if 1
679 #define FBIOSCURSOR32	_IOW('F', 24, struct netbsd32_fbcursor)
680 #define FBIOGCURSOR32	_IOWR('F', 25, struct netbsd32_fbcursor)
681 #endif
682 
683 /* from arch/sparc/include/openpromio.h */
684 struct netbsd32_opiocdesc {
685 	int	op_nodeid;		/* passed or returned node id */
686 	int	op_namelen;		/* length of op_name */
687 	netbsd32_charp op_name;		/* pointer to field name */
688 	int	op_buflen;		/* length of op_buf (value-result) */
689 	netbsd32_charp op_buf;		/* pointer to field value */
690 };
691 #if 1
692 #define	OPIOCGET32	_IOWR('O', 1, struct netbsd32_opiocdesc) /* get openprom field */
693 #define	OPIOCSET32	_IOW('O', 2, struct netbsd32_opiocdesc) /* set openprom field */
694 #define	OPIOCNEXTPROP32	_IOWR('O', 3, struct netbsd32_opiocdesc) /* get next property */
695 #endif
696 
697 /* prototypes for the converters */
698 static __inline void
699 netbsd32_to_fbcmap(struct netbsd32_fbcmap *, struct fbcmap *, u_long);
700 static __inline void
701 netbsd32_to_fbcursor(struct netbsd32_fbcursor *, struct fbcursor *, u_long);
702 static __inline void
703 netbsd32_to_opiocdesc(struct netbsd32_opiocdesc *, struct opiocdesc *, u_long);
704 
705 static __inline void
706 netbsd32_from_fbcmap(struct fbcmap *, struct netbsd32_fbcmap *);
707 static __inline void
708 netbsd32_from_fbcursor(struct fbcursor *, struct netbsd32_fbcursor *);
709 static __inline void
710 netbsd32_from_opiocdesc(struct opiocdesc *, struct netbsd32_opiocdesc *);
711 
712 /* convert to/from different structures */
713 static __inline void
714 netbsd32_to_fbcmap(s32p, p, cmd)
715 	struct netbsd32_fbcmap *s32p;
716 	struct fbcmap *p;
717 	u_long cmd;
718 {
719 
720 	p->index = s32p->index;
721 	p->count = s32p->count;
722 	p->red = (u_char *)(u_long)s32p->red;
723 	p->green = (u_char *)(u_long)s32p->green;
724 	p->blue = (u_char *)(u_long)s32p->blue;
725 }
726 
727 static __inline void
728 netbsd32_to_fbcursor(s32p, p, cmd)
729 	struct netbsd32_fbcursor *s32p;
730 	struct fbcursor *p;
731 	u_long cmd;
732 {
733 
734 	p->set = s32p->set;
735 	p->enable = s32p->enable;
736 	p->pos = s32p->pos;
737 	p->hot = s32p->hot;
738 	netbsd32_to_fbcmap(&s32p->cmap, &p->cmap, cmd);
739 	p->size = s32p->size;
740 	p->image = (char *)(u_long)s32p->image;
741 	p->mask = (char *)(u_long)s32p->mask;
742 }
743 
744 static __inline void
745 netbsd32_to_opiocdesc(s32p, p, cmd)
746 	struct netbsd32_opiocdesc *s32p;
747 	struct opiocdesc *p;
748 	u_long cmd;
749 {
750 
751 	p->op_nodeid = s32p->op_nodeid;
752 	p->op_namelen = s32p->op_namelen;
753 	p->op_name = (char *)(u_long)s32p->op_name;
754 	p->op_buflen = s32p->op_buflen;
755 	p->op_buf = (char *)(u_long)s32p->op_buf;
756 }
757 
758 static __inline void
759 netbsd32_from_fbcmap(p, s32p)
760 	struct fbcmap *p;
761 	struct netbsd32_fbcmap *s32p;
762 {
763 
764 	s32p->index = p->index;
765 	s32p->count = p->count;
766 /* filled in */
767 #if 0
768 	s32p->red = (netbsd32_u_charp)p->red;
769 	s32p->green = (netbsd32_u_charp)p->green;
770 	s32p->blue = (netbsd32_u_charp)p->blue;
771 #endif
772 }
773 
774 static __inline void
775 netbsd32_from_fbcursor(p, s32p)
776 	struct fbcursor *p;
777 	struct netbsd32_fbcursor *s32p;
778 {
779 
780 	s32p->set = p->set;
781 	s32p->enable = p->enable;
782 	s32p->pos = p->pos;
783 	s32p->hot = p->hot;
784 	netbsd32_from_fbcmap(&p->cmap, &s32p->cmap);
785 	s32p->size = p->size;
786 /* filled in */
787 #if 0
788 	s32p->image = (netbsd32_charp)p->image;
789 	s32p->mask = (netbsd32_charp)p->mask;
790 #endif
791 }
792 
793 static __inline void
794 netbsd32_from_opiocdesc(p, s32p)
795 	struct opiocdesc *p;
796 	struct netbsd32_opiocdesc *s32p;
797 {
798 
799 	s32p->op_nodeid = p->op_nodeid;
800 	s32p->op_namelen = p->op_namelen;
801 	s32p->op_name = (netbsd32_charp)(u_long)p->op_name;
802 	s32p->op_buflen = p->op_buflen;
803 	s32p->op_buf = (netbsd32_charp)(u_long)p->op_buf;
804 }
805 
806 int
807 netbsd32_md_ioctl(fp, com, data32, p)
808 	struct file *fp;
809 	netbsd32_u_long com;
810 	caddr_t data32;
811 	struct proc *p;
812 {
813 	u_int size;
814 	caddr_t data, memp = NULL;
815 #define STK_PARAMS	128
816 	u_long stkbuf[STK_PARAMS/sizeof(u_long)];
817 	int error;
818 
819 	switch (com) {
820 	case FBIOPUTCMAP32:
821 		IOCTL_STRUCT_CONV_TO(FBIOPUTCMAP, fbcmap);
822 	case FBIOGETCMAP32:
823 		IOCTL_STRUCT_CONV_TO(FBIOGETCMAP, fbcmap);
824 
825 	case FBIOSCURSOR32:
826 		IOCTL_STRUCT_CONV_TO(FBIOSCURSOR, fbcursor);
827 	case FBIOGCURSOR32:
828 		IOCTL_STRUCT_CONV_TO(FBIOGCURSOR, fbcursor);
829 
830 	case OPIOCGET32:
831 		IOCTL_STRUCT_CONV_TO(OPIOCGET, opiocdesc);
832 	case OPIOCSET32:
833 		IOCTL_STRUCT_CONV_TO(OPIOCSET, opiocdesc);
834 	case OPIOCNEXTPROP32:
835 		IOCTL_STRUCT_CONV_TO(OPIOCNEXTPROP, opiocdesc);
836 	default:
837 		error = (*fp->f_ops->fo_ioctl)(fp, com, data32, p);
838 	}
839 	if (memp)
840 		free(memp, M_IOCTLOPS);
841 	return (error);
842 }
843 
844 
845 int
846 netbsd32_sysarch(p, v, retval)
847 	struct proc *p;
848 	void *v;
849 	register_t *retval;
850 {
851 	struct netbsd32_sysarch_args /* {
852 		syscallarg(int) op;
853 		syscallarg(netbsd32_voidp) parms;
854 	} */ *uap = v;
855 
856 	switch (SCARG(uap, op)) {
857 	default:
858 		printf("(%s) netbsd32_sysarch(%d)\n", MACHINE, SCARG(uap, op));
859 		return EINVAL;
860 	}
861 }
862