1/* $NetBSD: svr4_32_machdep.c,v 1.37 2009/12/10 14:13:52 matt Exp $ */ 2 3/*- 4 * Copyright (c) 1994 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Christos Zoulas. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32#include <sys/cdefs.h> 33__KERNEL_RCSID(0, "$NetBSD: svr4_32_machdep.c,v 1.37 2009/12/10 14:13:52 matt Exp $"); 34 35#ifdef _KERNEL_OPT 36#include "opt_ddb.h" 37#endif 38 39#include <sys/param.h> 40#include <sys/systm.h> 41#include <sys/namei.h> 42#include <sys/proc.h> 43#include <sys/exec.h> 44#include <sys/filedesc.h> 45#include <sys/ioctl.h> 46#include <sys/kernel.h> 47#include <sys/signal.h> 48#include <sys/signalvar.h> 49#include <sys/malloc.h> 50#include <sys/mount.h> 51#include <sys/syscallargs.h> 52#include <sys/exec_elf.h> 53#include <sys/types.h> 54 55#include <uvm/uvm_param.h> 56 57#include <compat/svr4_32/svr4_32_types.h> 58#include <compat/svr4_32/svr4_32_lwp.h> 59#include <compat/svr4_32/svr4_32_ucontext.h> 60#include <compat/svr4_32/svr4_32_syscallargs.h> 61#include <compat/svr4_32/svr4_32_util.h> 62#include <compat/svr4_32/svr4_32_exec.h> 63#include <compat/netbsd32/netbsd32_exec.h> 64 65#include <machine/cpu.h> 66#include <machine/psl.h> 67#include <machine/reg.h> 68#include <machine/trap.h> 69#include <machine/vmparam.h> 70#include <machine/svr4_machdep.h> 71 72static void svr4_32_getsiginfo(union svr4_32_siginfo *, int, u_long, void *); 73 74void 75svr4_32_setregs(struct lwp *l, struct exec_package *epp, vaddr_t stack) 76{ 77 register struct trapframe64 *tf = l->l_md.md_tf; 78 79 netbsd32_setregs(l, epp, stack); 80 81 /* This should be the exit function, not p->p_psstrp. */ 82 tf->tf_global[1] = (vaddr_t)0; 83} 84 85#ifdef DEBUG 86#include <sparc64/sparc64/sigdebug.h> 87#endif 88 89#ifdef DEBUG_SVR4 90static void svr4_32_printmcontext(const char *, struct svr4_32_mcontext *); 91 92static void 93svr4_32_printmcontext(const char *fun, struct svr4_32_mcontext *mc) 94{ 95 svr4_32_greg_t *r = mc->greg; 96 97 printf("%s at %p\n", fun, mc); 98 99 printf("Regs: "); 100 printf("TSTATE = 0x%x ", r[SVR4_SPARC_PSR]); 101 printf("PC = 0x%x ", r[SVR4_SPARC_PC]); 102 printf("nPC = 0x%x ", r[SVR4_SPARC_nPC]); 103 printf("Y = 0x%x ", r[SVR4_SPARC_Y]); 104 printf("G1 = 0x%x ", r[SVR4_SPARC_G1]); 105 printf("G2 = 0x%x ", r[SVR4_SPARC_G2]); 106 printf("G3 = 0x%x ", r[SVR4_SPARC_G3]); 107 printf("G4 = 0x%x ", r[SVR4_SPARC_G4]); 108 printf("G5 = 0x%x ", r[SVR4_SPARC_G5]); 109 printf("G6 = 0x%x ", r[SVR4_SPARC_G6]); 110 printf("G7 = 0x%x ", r[SVR4_SPARC_G7]); 111 printf("O0 = 0x%x ", r[SVR4_SPARC_O0]); 112 printf("O1 = 0x%x ", r[SVR4_SPARC_O1]); 113 printf("O2 = 0x%x ", r[SVR4_SPARC_O2]); 114 printf("O3 = 0x%x ", r[SVR4_SPARC_O3]); 115 printf("O4 = 0x%x ", r[SVR4_SPARC_O4]); 116 printf("O5 = 0x%x ", r[SVR4_SPARC_O5]); 117 printf("O6 = 0x%x ", r[SVR4_SPARC_O6]); 118 printf("O7 = 0x%x ", r[SVR4_SPARC_O7]); 119 printf("\n"); 120} 121#endif 122 123void * 124svr4_32_getmcontext(struct lwp *l, struct svr4_32_mcontext *mc, 125 netbsd32_u_long *flags) 126{ 127 struct trapframe64 *tf = (struct trapframe64 *)l->l_md.md_tf; 128 svr4_32_greg_t *r = mc->greg; 129#ifdef FPU_CONTEXT 130 svr4_32_fregset_t *f = &mc->freg; 131 struct fpstate *fps = l->l_md.md_fpstate; 132#endif 133 134 write_user_windows(); 135 if (rwindow_save(l)) { 136#ifdef DEBUG 137 printf("svr4_32_getcontext: rwindow_save(%p) failed, sending SIGILL\n", l); 138#ifdef DDB 139 Debugger(); 140#endif 141#endif 142 mutex_enter(l->l_proc->p_lock); 143 sigexit(l, SIGILL); 144 } 145 146 /* 147 * Get the general purpose registers 148 */ 149 r[SVR4_SPARC_PSR] = TSTATECCR_TO_PSR(tf->tf_tstate); 150 r[SVR4_SPARC_PC] = tf->tf_pc; 151 r[SVR4_SPARC_nPC] = tf->tf_npc; 152 r[SVR4_SPARC_Y] = tf->tf_y; 153 r[SVR4_SPARC_G1] = tf->tf_global[1]; 154 r[SVR4_SPARC_G2] = tf->tf_global[2]; 155 r[SVR4_SPARC_G3] = tf->tf_global[3]; 156 r[SVR4_SPARC_G4] = tf->tf_global[4]; 157 r[SVR4_SPARC_G5] = tf->tf_global[5]; 158 r[SVR4_SPARC_G6] = tf->tf_global[6]; 159 r[SVR4_SPARC_G7] = tf->tf_global[7]; 160 r[SVR4_SPARC_O0] = tf->tf_out[0]; 161 r[SVR4_SPARC_O1] = tf->tf_out[1]; 162 r[SVR4_SPARC_O2] = tf->tf_out[2]; 163 r[SVR4_SPARC_O3] = tf->tf_out[3]; 164 r[SVR4_SPARC_O4] = tf->tf_out[4]; 165 r[SVR4_SPARC_O5] = tf->tf_out[5]; 166 r[SVR4_SPARC_O6] = tf->tf_out[6]; 167 r[SVR4_SPARC_O7] = tf->tf_out[7]; 168 169 *flags |= SVR4_UC_CPU; 170 171#ifdef FPU_CONTEXT 172 /* 173 * Get the floating point registers 174 */ 175 /* Note: copies only pre-v9 floating point registers. */ 176 memcpy(f->fpu_regs, fps->fs_regs, sizeof(f->fpu_regs)); 177 f->fp_nqsize = sizeof(struct fp_qentry); 178 f->fp_nqel = fps->fs_qsize; 179 f->fp_fsr = fps->fs_fsr; 180 if (f->fp_q != NULL) { 181 size_t sz = f->fp_nqel * f->fp_nqsize; 182 if (sz > sizeof(fps->fs_queue)) { 183#ifdef DIAGNOSTIC 184 printf("getcontext: fp_queue too large\n"); 185#endif 186 return; 187 } 188 if (copyout(fps->fs_queue, (void *)(u_long)f->fp_q, sz) != 0) { 189#ifdef DIAGNOSTIC 190 printf("getcontext: copy of fp_queue failed %d\n", 191 error); 192#endif 193 return; 194 } 195 } 196 f->fp_busy = 0; /* XXX: How do we determine that? */ 197 *flags |= SVR4_UC_FPU; 198#endif 199 200 201#ifdef DEBUG_SVR4 202 svr4_32_printmcontext("getmcontext", mc); 203#endif 204 return (void *)(u_long)tf->tf_out[6]; 205} 206 207 208/* 209 * Set to mcontext specified. 210 * Return to previous pc and psl as specified by 211 * context left by sendsig. Check carefully to 212 * make sure that the user has not modified the 213 * psl to gain improper privileges or to cause 214 * a machine fault. 215 * This is almost like sigreturn() and it shows. 216 */ 217int 218svr4_32_setmcontext(struct lwp *l, struct svr4_32_mcontext *mc, 219 netbsd32_u_long flags) 220{ 221 register struct trapframe64 *tf; 222 svr4_32_greg_t *r = mc->greg; 223#ifdef FPU_CONTEXT 224 svr4_32_fregset_t *f = &mc->freg; 225 struct fpstate64 *fps = p->p_md.md_fpstate; 226#endif 227 228#ifdef DEBUG_SVR4 229 svr4_32_printmcontext("setmcontext", uc); 230#endif 231 232 write_user_windows(); 233 if (rwindow_save(l)) { 234#ifdef DEBUG 235 printf("svr4_32_setcontext: rwindow_save(%p) failed, sending SIGILL\n", l); 236#ifdef DDB 237 Debugger(); 238#endif 239#endif 240 mutex_enter(l->l_proc->p_lock); 241 sigexit(l, SIGILL); 242 } 243 244#ifdef DEBUG 245 if (sigdebug & SDB_FOLLOW) 246 printf("svr4_32_setmcontext: %s[%d], svr4_32_mcontext %p\n", 247 l->l_proc->p_comm, l->l_proc->p_pid, mc); 248#endif 249 250 if (flags & SVR4_UC_CPU) { 251 /* Restore register context. */ 252 tf = (struct trapframe64 *)l->l_md.md_tf; 253 254 /* 255 * Only the icc bits in the psr are used, so it need not be 256 * verified. pc and npc must be multiples of 4. This is all 257 * that is required; if it holds, just do it. 258 */ 259 if (((r[SVR4_SPARC_PC] | r[SVR4_SPARC_nPC]) & 3) != 0) { 260 printf("pc or npc are not multiples of 4!\n"); 261 return EINVAL; 262 } 263 264 /* take only psr ICC field */ 265 tf->tf_tstate = (tf->tf_tstate & ~TSTATE_CCR) | 266 PSRCC_TO_TSTATE(r[SVR4_SPARC_PSR]); 267 tf->tf_pc = r[SVR4_SPARC_PC]; 268 tf->tf_npc = r[SVR4_SPARC_nPC]; 269 tf->tf_y = r[SVR4_SPARC_Y]; 270 271 /* Restore everything */ 272 tf->tf_global[1] = r[SVR4_SPARC_G1]; 273 tf->tf_global[2] = r[SVR4_SPARC_G2]; 274 tf->tf_global[3] = r[SVR4_SPARC_G3]; 275 tf->tf_global[4] = r[SVR4_SPARC_G4]; 276 tf->tf_global[5] = r[SVR4_SPARC_G5]; 277 tf->tf_global[6] = r[SVR4_SPARC_G6]; 278 tf->tf_global[7] = r[SVR4_SPARC_G7]; 279 280 tf->tf_out[0] = r[SVR4_SPARC_O0]; 281 tf->tf_out[1] = r[SVR4_SPARC_O1]; 282 tf->tf_out[2] = r[SVR4_SPARC_O2]; 283 tf->tf_out[3] = r[SVR4_SPARC_O3]; 284 tf->tf_out[4] = r[SVR4_SPARC_O4]; 285 tf->tf_out[5] = r[SVR4_SPARC_O5]; 286 tf->tf_out[6] = r[SVR4_SPARC_O6]; 287 tf->tf_out[7] = r[SVR4_SPARC_O7]; 288 } 289 290 291#ifdef FPU_CONTEXT 292 if (flags & SVR4_UC_FPU) { 293 /* 294 * Set the floating point registers 295 */ 296 int error; 297 size_t sz = f->fp_nqel * f->fp_nqsize; 298 if (sz > sizeof(fps->fs_queue)) { 299#ifdef DIAGNOSTIC 300 printf("setmcontext: fp_queue too large\n"); 301#endif 302 return EINVAL; 303 } 304 /* Note: touches only pre-v9 floating point registers. */ 305 memcpy(fps->fs_regs, f->fpu_regs, sizeof(f->fpu_regs)); 306 fps->fs_qsize = f->fp_nqel; 307 fps->fs_fsr = f->fp_fsr; 308 if (f->fp_q != 0) { 309 if ((error = copyin((void *)(u_long)f->fp_q, 310 fps->fs_queue, 311 f->fp_nqel * f->fp_nqsize)) != 0) { 312#ifdef DIAGNOSTIC 313 printf("setmcontext: fp_queue copy failed\n"); 314#endif 315 return error; 316 } 317 } 318 } 319#endif 320 321 return 0; 322} 323 324/* 325 * map the trap code into the svr4 siginfo as best we can 326 */ 327static void 328svr4_32_getsiginfo(union svr4_32_siginfo *si, int sig, u_long code, 329 void *addr) 330{ 331 si->si_signo = native_to_svr4_signo[sig]; 332 si->si_errno = 0; 333 NETBSD32PTR32(si->si_addr, addr); 334 /* 335 * we can do this direct map as they are the same as all sparc 336 * architectures. 337 */ 338 si->si_trap = code; 339 switch (code) { 340 case T_POR: 341 case T_WDR: 342 case T_XIR: 343 case T_SIR: 344 case T_RED_EXCEPTION: 345 si->si_code = 0; 346 break; 347 348 case T_TEXTFAULT: 349 si->si_code = SVR4_BUS_ADRALN; 350 break; 351 352 case T_ILLINST: 353 si->si_code = SVR4_ILL_ILLOPC; 354 break; 355 356 case T_PRIVINST: 357 si->si_code = SVR4_ILL_PRVOPC; 358 break; 359 360 case T_FPDISABLED: 361 si->si_code = SVR4_FPE_FLTINV; 362 break; 363 364 case T_ALIGN: 365 si->si_code = SVR4_BUS_ADRALN; 366 break; 367 368 case T_FP_IEEE_754: 369 case T_FP_OTHER: 370 si->si_code = SVR4_FPE_FLTINV; 371 break; 372 373 case T_DATAFAULT: 374 si->si_code = SVR4_BUS_ADRALN; 375 break; 376 377 case T_TAGOF: 378 si->si_code = SVR4_EMT_TAGOVF; 379 break; 380 381 case T_IDIV0: 382 si->si_code = SVR4_FPE_INTDIV; 383 break; 384 385 case T_INTOF: 386 si->si_code = SVR4_FPE_INTOVF; 387 break; 388 389 case T_BREAKPOINT: 390 si->si_code = SVR4_TRAP_BRKPT; 391 break; 392 393 /* 394 * XXX - hardware traps with unknown code 395 */ 396 case T_L1INT: 397 case T_L2INT: 398 case T_L3INT: 399 case T_L4INT: 400 case T_L5INT: 401 case T_L6INT: 402 case T_L7INT: 403 case T_L8INT: 404 case T_L9INT: 405 case T_L10INT: 406 case T_L11INT: 407 case T_L12INT: 408 case T_L13INT: 409 case T_L14INT: 410 case T_L15INT: 411 si->si_code = 0; 412 break; 413 414 /* 415 * XXX - software traps with unknown code 416 */ 417 case T_SUN_SYSCALL: 418 case T_FLUSHWIN: 419 case T_CLEANWIN: 420 case T_RANGECHECK: 421 case T_FIXALIGN: 422 case T_SVR4_SYSCALL: 423 case T_BSD_SYSCALL: 424 case T_KGDB_EXEC: 425 si->si_code = 0; 426 break; 427 428 default: 429 si->si_code = 0; 430#ifdef notyet 431 /* 432 * XXX: in trap.c, code gets passed the address 433 * of the fault! not the trap code on SEGV! 434 */ 435#ifdef DIAGNOSTIC 436 printf("sig %d code %ld\n", sig, code); 437 panic("svr4_32_getsiginfo"); 438#endif 439#endif 440 break; 441 } 442} 443 444/* 445 * Send an interrupt to process. 446 * 447 * Stack is set up to allow sigcode stored 448 * in u. to call routine. After the handler is 449 * done svr4 will call setcontext for us 450 * with the user context we just set up, and we 451 * will return to the user pc, psl. 452 */ 453void 454svr4_32_sendsig(const ksiginfo_t *ksi, const sigset_t *mask) 455{ 456 int sig = ksi->ksi_signo; 457 register struct lwp *l = curlwp; 458 struct proc *p = l->l_proc; 459 register struct trapframe64 *tf; 460 struct svr4_32_sigframe *fp, frame; 461 int onstack, error; 462 vaddr_t oldsp, newsp, addr; 463 sig_t catcher = SIGACTION(p, sig).sa_handler; 464 sigset_t tmask; 465 466 tf = (struct trapframe64 *)l->l_md.md_tf; 467 oldsp = tf->tf_out[6]; 468 469 /* Do we need to jump onto the signal stack? */ 470 onstack = 471 (l->l_sigstk.ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 && 472 (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0; 473 474 /* 475 * Allocate space for the signal handler context. 476 */ 477 if (onstack) 478 fp = (struct svr4_32_sigframe *)((char *)l->l_sigstk.ss_sp + 479 l->l_sigstk.ss_size); 480 else 481 fp = (struct svr4_32_sigframe *)oldsp; 482 fp = (struct svr4_32_sigframe *) ((long) (fp - 1) & ~7); 483 484#ifdef DEBUG 485 sigpid = p->p_pid; 486 if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) { 487 printf("svr4_32_sendsig: %s[%d] sig %d newusp %p scp %p oldsp %p\n", 488 p->p_comm, p->p_pid, sig, fp, &fp->sf_uc, (void *)(u_long)oldsp); 489#ifdef DDB 490 if (sigdebug & SDB_DDB) Debugger(); 491#endif 492 } 493#endif 494 /* 495 * Build the argument list for the signal handler. 496 */ 497 svr4_32_getsiginfo(&frame.sf_si, sig, ksi->ksi_trap, 498 (void *)(u_long)tf->tf_pc); 499 500 /* Build stack frame for signal trampoline. */ 501 frame.sf_signum = frame.sf_si.si_signo; 502 NETBSD32PTR32(frame.sf_sip, &fp->sf_si); 503 NETBSD32PTR32(frame.sf_ucp, &fp->sf_uc); 504 frame.sf_handler = catcher; 505 506 DPRINTF(("svr4_32_sendsig signum=%d si = %p uc = %p handler = %p\n", 507 frame.sf_signum, frame.sf_sip, 508 frame.sf_ucp, frame.sf_handler)); 509 /* 510 * Modify the signal context to be used by sigreturn. 511 */ 512 tmask = *mask; 513 sendsig_reset(l, sig); 514 frame.sf_uc.uc_mcontext.greg[SVR4_SPARC_SP] = oldsp; 515 newsp = (u_long)fp - sizeof(struct rwindow32); 516 mutex_exit(p->p_lock); 517 svr4_32_getcontext(l, &frame.sf_uc, &tmask); 518 write_user_windows(); 519 520#ifdef DEBUG 521 if ((sigdebug & SDB_KSTACK)) 522 printf("svr4_32_sendsig: saving sf to %p, setting stack pointer %p to %p\n", 523 fp, &(((struct rwindow32 *)newsp)->rw_in[6]), (void *)(u_long)oldsp); 524#endif 525 error = (rwindow_save(l) || copyout(&frame, fp, sizeof(frame)) != 0 || 526 copyout(&oldsp, &((struct rwindow32 *)newsp)->rw_in[6], sizeof(oldsp))); 527 mutex_enter(p->p_lock); 528 529 if (error) { 530 /* 531 * Process has trashed its stack; give it an illegal 532 * instruction to halt it in its tracks. 533 */ 534#ifdef DEBUG 535 mutex_exit(p->p_lock); 536 if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) 537 printf("svr4_32_sendsig: window save or copyout error\n"); 538 printf("svr4_32_sendsig: stack was trashed trying to send sig %d, sending SIGILL\n", sig); 539#ifdef DDB 540 Debugger(); 541#endif 542 mutex_enter(p->p_lock); 543#endif 544 sigexit(l, SIGILL); 545 /* NOTREACHED */ 546 } 547 548#ifdef DEBUG 549 if (sigdebug & SDB_FOLLOW) { 550 printf("svr4_32_sendsig: %s[%d] sig %d scp %p\n", 551 p->p_comm, p->p_pid, sig, &fp->sf_uc); 552 } 553#endif 554 /* 555 * Build context to run handler in. 556 */ 557 addr = (vaddr_t)p->p_sigctx.ps_sigcode; 558 tf->tf_pc = addr; 559 tf->tf_npc = addr + 4; 560 tf->tf_global[1] = (vaddr_t)catcher; 561 tf->tf_out[6] = newsp; 562 563 /* Remember that we're now on the signal stack. */ 564 if (onstack) 565 l->l_sigstk.ss_flags |= SS_ONSTACK; 566#ifdef DEBUG 567 if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) { 568 mutex_exit(p->p_lock); 569 printf("svr4_32_sendsig: about to return to catcher %p thru %p\n", 570 catcher, (void *)(u_long)addr); 571#ifdef DDB 572 if (sigdebug & SDB_DDB) Debugger(); 573#endif 574 mutex_enter(p->p_lock); 575 } 576#endif 577} 578 579 580#define ADVANCE (n = tf->tf_npc, tf->tf_pc = n, tf->tf_npc = n + 4) 581int 582svr4_32_trap(int type, struct lwp *l) 583{ 584 int n; 585 struct proc *p = l->l_proc; 586 struct trapframe64 *tf = l->l_md.md_tf; 587 struct timespec ts; 588 struct timeval tv; 589 struct timeval rtime, stime; 590 uint64_t tm; 591 592 if (p->p_emul != &emul_svr4_32) 593 return 0; 594 595 switch (type) { 596 case T_SVR4_GETCC: 597 uprintf("T_SVR4_GETCC\n"); 598 break; 599 600 case T_SVR4_SETCC: 601 uprintf("T_SVR4_SETCC\n"); 602 break; 603 604 case T_SVR4_GETPSR: 605 tf->tf_out[0] = TSTATECCR_TO_PSR(tf->tf_tstate); 606 break; 607 608 case T_SVR4_SETPSR: 609 uprintf("T_SVR4_SETPSR\n"); 610 break; 611 612 case T_SVR4_GETHRTIME: 613 /* 614 * This is like gethrtime(3), returning the time expressed 615 * in nanoseconds since an arbitrary time in the past and 616 * guaranteed to be monotonically increasing, which we 617 * obtain from nanouptime(9). 618 */ 619 nanouptime(&ts); 620 621 tm = ts.tv_nsec; 622 tm += ts.tv_sec * (uint64_t)1000000000u; 623 tf->tf_out[0] = (tm >> 32) & 0x00000000ffffffffffUL; 624 tf->tf_out[1] = tm & 0x00000000ffffffffffUL; 625 break; 626 627 case T_SVR4_GETHRVTIME: 628 /* 629 * This is like gethrvtime(3). returning the LWP's (now: 630 * proc's) virtual time expressed in nanoseconds. It is 631 * supposedly guaranteed to be monotonically increasing, but 632 * for now using the process's real time augmented with its 633 * current runtime is the best we can do. 634 */ 635 microtime(&tv); 636 bintime2timeval(&l->l_rtime, &rtime); 637 bintime2timeval(&l->l_stime, &stime); 638 639 tm = (rtime.tv_sec + tv.tv_sec - stime.tv_sec) * 1000000ull; 640 tm += rtime.tv_usec + tv.tv_usec; 641 tm -= stime.tv_usec; 642 tm *= 1000u; 643 tf->tf_out[0] = (tm >> 32) & 0x00000000ffffffffffUL; 644 tf->tf_out[1] = tm & 0x00000000ffffffffffUL; 645 break; 646 647 case T_SVR4_GETHRESTIME: 648 /* I assume this is like gettimeofday(3) */ 649 nanotime(&ts); 650 tf->tf_out[0] = ts.tv_sec; 651 tf->tf_out[1] = ts.tv_nsec; 652 break; 653 654 default: 655 return 0; 656 } 657 658 ADVANCE; 659 return 1; 660} 661 662/* 663 */ 664int 665svr4_32_sys_sysarch(struct lwp *l, const struct svr4_32_sys_sysarch_args *uap, register_t *retval) 666{ 667 668 switch (SCARG(uap, op)) { 669 default: 670 printf("(sparc) svr4_32_sysarch(%d)\n", SCARG(uap, op)); 671 return EINVAL; 672 } 673} 674 675vaddr_t 676svr4_32_vm_default_addr(struct proc *p, vaddr_t base, vsize_t size) 677{ 678 return round_page((vaddr_t)(base) + (vsize_t)MAXDSIZ32); 679} 680