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 = ≻ 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 = ≻ 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