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