Annotation of sys/arch/hp300/hp300/hpux_machdep.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: hpux_machdep.c,v 1.20 2005/11/06 17:23:39 miod Exp $ */
! 2: /* $NetBSD: hpux_machdep.c,v 1.19 1998/02/16 20:58:30 thorpej Exp $ */
! 3:
! 4: /*
! 5: * Copyright (c) 1995, 1996, 1997 Jason R. Thorpe. All rights reserved.
! 6: * Copyright (c) 1988 University of Utah.
! 7: * Copyright (c) 1990, 1993
! 8: * The Regents of the University of California. All rights reserved.
! 9: *
! 10: * This code is derived from software contributed to Berkeley by
! 11: * the Systems Programming Group of the University of Utah Computer
! 12: * Science Department.
! 13: *
! 14: * Redistribution and use in source and binary forms, with or without
! 15: * modification, are permitted provided that the following conditions
! 16: * are met:
! 17: * 1. Redistributions of source code must retain the above copyright
! 18: * notice, this list of conditions and the following disclaimer.
! 19: * 2. Redistributions in binary form must reproduce the above copyright
! 20: * notice, this list of conditions and the following disclaimer in the
! 21: * documentation and/or other materials provided with the distribution.
! 22: * 3. The name of the author may not be used to endorse or promote products
! 23: * derived from this software without specific prior written permission.
! 24: *
! 25: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
! 26: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 27: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 28: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
! 29: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 30: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 31: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 32: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 33: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 34: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 35: * SUCH DAMAGE.
! 36: */
! 37:
! 38: /*
! 39: * Machine-dependent bits for HP-UX binary compatibility.
! 40: */
! 41:
! 42: #include <sys/param.h>
! 43: #include <sys/systm.h>
! 44: #include <sys/buf.h>
! 45: #include <sys/conf.h>
! 46: #include <sys/device.h>
! 47: #include <sys/exec.h>
! 48: #include <sys/file.h>
! 49: #include <sys/filedesc.h>
! 50: #include <sys/ioctl.h>
! 51: #include <sys/ipc.h>
! 52: #include <sys/kernel.h>
! 53: #include <sys/malloc.h>
! 54: #include <sys/mman.h>
! 55: #include <sys/mount.h>
! 56: #include <sys/namei.h>
! 57: #include <sys/poll.h>
! 58: #include <sys/proc.h>
! 59: #include <sys/ptrace.h>
! 60: #include <sys/signalvar.h>
! 61: #include <sys/stat.h>
! 62: #include <sys/syslog.h>
! 63: #include <sys/tty.h>
! 64: #include <sys/user.h>
! 65: #include <sys/vnode.h>
! 66: #include <sys/wait.h>
! 67:
! 68: #include <machine/cpu.h>
! 69: #include <machine/reg.h>
! 70: #include <machine/psl.h>
! 71: #include <machine/vmparam.h>
! 72:
! 73: #include <uvm/uvm_extern.h>
! 74:
! 75: #include <sys/syscallargs.h>
! 76:
! 77: #include <compat/hpux/hpux.h>
! 78: #include <compat/hpux/hpux_sig.h>
! 79: #include <compat/hpux/hpux_util.h>
! 80: #include <compat/hpux/hpux_syscall.h>
! 81: #include <compat/hpux/hpux_syscallargs.h>
! 82:
! 83: #include <machine/hpux_machdep.h>
! 84:
! 85: extern short exframesize[];
! 86:
! 87: struct valtostr {
! 88: int val;
! 89: const char *str;
! 90: };
! 91:
! 92: /*
! 93: * 6.0 and later context.
! 94: * XXX what are the HP-UX "localroot" semantics? Should we handle
! 95: * XXX diskless systems here?
! 96: */
! 97: static const char context_040[] =
! 98: "standalone HP-MC68040 HP-MC68881 HP-MC68020 HP-MC68010 localroot default";
! 99:
! 100: static const char context_fpu[] =
! 101: "standalone HP-MC68881 HP-MC68020 HP-MC68010 localroot default";
! 102:
! 103: static const char context_nofpu[] =
! 104: "standalone HP-MC68020 HP-MC68010 localroot default";
! 105:
! 106: static struct valtostr context_table[] = {
! 107: { FPU_68060, &context_040[0] },
! 108: { FPU_68040, &context_040[0] },
! 109: { FPU_68882, &context_fpu[0] },
! 110: { FPU_68881, &context_fpu[0] },
! 111: { 0, NULL },
! 112: };
! 113:
! 114: #define UOFF(f) ((int)&((struct user *)0)->f)
! 115: #define HPUOFF(f) ((int)&((struct hpux_user *)0)->f)
! 116:
! 117: /* simplified FP structure */
! 118: struct bsdfp {
! 119: int save[54];
! 120: int reg[24];
! 121: int ctrl[3];
! 122: };
! 123:
! 124: /*
! 125: * m68k-specific setup for HP-UX executables.
! 126: */
! 127: int
! 128: hpux_cpu_makecmds(p, epp)
! 129: struct proc *p;
! 130: struct exec_package *epp;
! 131: {
! 132: /* struct hpux_exec *hpux_ep = epp->ep_hdr; */
! 133:
! 134: /* set up command for exec header */
! 135: NEW_VMCMD(&epp->ep_vmcmds, hpux_cpu_vmcmd,
! 136: sizeof(struct hpux_exec), (long)epp->ep_hdr, NULLVP, 0, 0);
! 137: return (0);
! 138: }
! 139:
! 140: /*
! 141: * We need to stash the exec header in the pcb, so we define
! 142: * this vmcmd to do it for us, since vmcmds are executed once
! 143: * we're committed to the exec (i.e. the old program has been unmapped).
! 144: *
! 145: * The address of the header is in ev->ev_addr and the length is
! 146: * in ev->ev_len.
! 147: */
! 148: int
! 149: hpux_cpu_vmcmd(p, ev)
! 150: struct proc *p;
! 151: struct exec_vmcmd *ev;
! 152: {
! 153: struct hpux_exec *execp = (struct hpux_exec *)ev->ev_addr;
! 154:
! 155: /* Make sure we have room. */
! 156: if (ev->ev_len <= sizeof(p->p_addr->u_md.md_exec))
! 157: bcopy((caddr_t)ev->ev_addr, p->p_addr->u_md.md_exec,
! 158: ev->ev_len);
! 159:
! 160: /* Deal with misc. HP-UX process attributes. */
! 161: if (execp->ha_trsize & HPUXM_VALID) {
! 162: if (execp->ha_trsize & HPUXM_DATAWT)
! 163: p->p_md.md_flags &= ~MDP_CCBDATA;
! 164:
! 165: if (execp->ha_trsize & HPUXM_STKWT)
! 166: p->p_md.md_flags &= ~MDP_CCBSTACK;
! 167: }
! 168:
! 169: return (0);
! 170: }
! 171:
! 172: /*
! 173: * Return arch-type for hpux_sys_sysconf()
! 174: */
! 175: int
! 176: hpux_cpu_sysconf_arch()
! 177: {
! 178:
! 179: switch (cputype) {
! 180: case CPU_68020:
! 181: return (HPUX_SYSCONF_CPUM020);
! 182:
! 183: case CPU_68030:
! 184: return (HPUX_SYSCONF_CPUM030);
! 185:
! 186: default:
! 187: return (HPUX_SYSCONF_CPUM040);
! 188: }
! 189: /* NOTREACHED */
! 190: }
! 191:
! 192: /*
! 193: * HP-UX advise(2) system call.
! 194: */
! 195: int
! 196: hpux_sys_advise(p, v, retval)
! 197: struct proc *p;
! 198: void *v;
! 199: register_t *retval;
! 200: {
! 201: struct hpux_sys_advise_args *uap = v;
! 202: int error = 0;
! 203:
! 204: switch (SCARG(uap, arg)) {
! 205: case 0:
! 206: p->p_md.md_flags |= MDP_HPUXMMAP;
! 207: break;
! 208:
! 209: case 1:
! 210: ICIA();
! 211: break;
! 212:
! 213: case 2:
! 214: DCIA();
! 215: break;
! 216:
! 217: default:
! 218: error = EINVAL;
! 219: break;
! 220: }
! 221:
! 222: return (error);
! 223: }
! 224:
! 225: /*
! 226: * HP-UX getcontext(2) system call.
! 227: * Man page lies, behaviour here is based on observed behaviour.
! 228: */
! 229: int
! 230: hpux_sys_getcontext(p, v, retval)
! 231: struct proc *p;
! 232: void *v;
! 233: register_t *retval;
! 234: {
! 235: struct hpux_sys_getcontext_args *uap = v;
! 236: const char *str;
! 237: int l, i, error = 0;
! 238: int len;
! 239:
! 240: if (SCARG(uap, len) <= 0)
! 241: return (EINVAL);
! 242:
! 243: for (i = 0; context_table[i].str != NULL; i++)
! 244: if (context_table[i].val == fputype)
! 245: break;
! 246: if (context_table[i].str == NULL)
! 247: str = &context_nofpu[0];
! 248: else
! 249: str = context_table[i].str;
! 250:
! 251: /* + 1 ... count the terminating \0. */
! 252: l = strlen(str) + 1;
! 253: len = min(SCARG(uap, len), l);
! 254:
! 255: if (len)
! 256: error = copyout(str, SCARG(uap, buf), len);
! 257: if (error == 0)
! 258: *retval = l;
! 259: return (0);
! 260: }
! 261:
! 262: /*
! 263: * Brutal hack! Map HP-UX u-area offsets into BSD k-stack offsets.
! 264: * XXX This probably doesn't work anymore, BTW. --thorpej
! 265: */
! 266: int
! 267: hpux_to_bsd_uoff(off, isps, p)
! 268: int *off, *isps;
! 269: struct proc *p;
! 270: {
! 271: int *ar0 = p->p_md.md_regs;
! 272: struct hpux_fp *hp;
! 273: struct bsdfp *bp;
! 274: u_int raddr;
! 275:
! 276: *isps = 0;
! 277:
! 278: /* u_ar0 field; procxmt puts in U_ar0 */
! 279: if ((int)off == HPUOFF(hpuxu_ar0))
! 280: return(UOFF(U_ar0));
! 281:
! 282: if (fputype) {
! 283: /* FP registers from PCB */
! 284: hp = (struct hpux_fp *)HPUOFF(hpuxu_fp);
! 285: bp = (struct bsdfp *)UOFF(u_pcb.pcb_fpregs);
! 286:
! 287: if (off >= hp->hpfp_ctrl && off < &hp->hpfp_ctrl[3])
! 288: return((int)&bp->ctrl[off - hp->hpfp_ctrl]);
! 289:
! 290: if (off >= hp->hpfp_reg && off < &hp->hpfp_reg[24])
! 291: return((int)&bp->reg[off - hp->hpfp_reg]);
! 292: }
! 293:
! 294: /*
! 295: * Everything else we recognize comes from the kernel stack,
! 296: * so we convert off to an absolute address (if not already)
! 297: * for simplicity.
! 298: */
! 299: if (off < (int *)ctob(UPAGES))
! 300: off = (int *)((u_int)off + (u_int)p->p_addr); /* XXX */
! 301:
! 302: /*
! 303: * General registers.
! 304: * We know that the HP-UX registers are in the same order as ours.
! 305: * The only difference is that their PS is 2 bytes instead of a
! 306: * padded 4 like ours throwing the alignment off.
! 307: */
! 308: if (off >= ar0 && off < &ar0[18]) {
! 309: /*
! 310: * PS: return low word and high word of PC as HP-UX would
! 311: * (e.g. &u.u_ar0[16.5]).
! 312: *
! 313: * XXX we don't do this since HP-UX adb doesn't rely on
! 314: * it and passing such an offset to procxmt will cause
! 315: * it to fail anyway. Instead, we just set the offset
! 316: * to PS and let hpux_ptrace() shift up the value returned.
! 317: */
! 318: if (off == &ar0[PS]) {
! 319: #if 0
! 320: raddr = (u_int) &((short *)ar0)[PS*2+1];
! 321: #else
! 322: raddr = (u_int) &ar0[(int)(off - ar0)];
! 323: #endif
! 324: *isps = 1;
! 325: }
! 326: /*
! 327: * PC: off will be &u.u_ar0[16.5] since HP-UX saved PS
! 328: * is only 16 bits.
! 329: */
! 330: else if (off == (int *)&(((short *)ar0)[PS*2+1]))
! 331: raddr = (u_int) &ar0[PC];
! 332: /*
! 333: * D0-D7, A0-A7: easy
! 334: */
! 335: else
! 336: raddr = (u_int) &ar0[(int)(off - ar0)];
! 337: return((int)(raddr - (u_int)p->p_addr)); /* XXX */
! 338: }
! 339:
! 340: /* everything else */
! 341: return (-1);
! 342: }
! 343:
! 344: #define HSS_RTEFRAME 0x01
! 345: #define HSS_FPSTATE 0x02
! 346: #define HSS_USERREGS 0x04
! 347:
! 348: struct hpuxsigstate {
! 349: int hss_flags; /* which of the following are valid */
! 350: struct frame hss_frame; /* original exception frame */
! 351: struct fpframe hss_fpstate; /* 68881/68882 state info */
! 352: };
! 353:
! 354: /*
! 355: * WARNING: code in locore.s assumes the layout shown here for hsf_signum
! 356: * thru hsf_handler so... don't screw with them!
! 357: */
! 358: struct hpuxsigframe {
! 359: int hsf_signum; /* signo for handler */
! 360: int hsf_code; /* additional info for handler */
! 361: struct hpuxsigcontext *hsf_scp; /* context ptr for handler */
! 362: sig_t hsf_handler; /* handler addr for u_sigc */
! 363: struct hpuxsigstate hsf_sigstate; /* state of the hardware */
! 364: struct hpuxsigcontext hsf_sc; /* actual context */
! 365: };
! 366:
! 367: #ifdef DEBUG
! 368: int hpuxsigdebug = 0;
! 369: int hpuxsigpid = 0;
! 370: #define SDB_FOLLOW 0x01
! 371: #define SDB_KSTACK 0x02
! 372: #define SDB_FPSTATE 0x04
! 373: #endif
! 374:
! 375: /*
! 376: * Send an interrupt to process.
! 377: */
! 378: /* ARGSUSED */
! 379: void
! 380: hpux_sendsig(catcher, sig, mask, code, type, val)
! 381: sig_t catcher;
! 382: int sig, mask;
! 383: u_long code;
! 384: int type;
! 385: union sigval val;
! 386: {
! 387: struct proc *p = curproc;
! 388: struct hpuxsigframe *kfp, *fp;
! 389: struct frame *frame;
! 390: struct sigacts *psp = p->p_sigacts;
! 391: short ft;
! 392: int oonstack, fsize;
! 393:
! 394: frame = (struct frame *)p->p_md.md_regs;
! 395: ft = frame->f_format;
! 396: oonstack = psp->ps_sigstk.ss_flags & SS_ONSTACK;
! 397:
! 398: /*
! 399: * Allocate and validate space for the signal handler
! 400: * context. Note that if the stack is in P0 space, the
! 401: * call to grow() is a nop, and the useracc() check
! 402: * will fail if the process has not already allocated
! 403: * the space with a `brk'.
! 404: */
! 405: fsize = sizeof(struct hpuxsigframe);
! 406: if ((psp->ps_flags & SAS_ALTSTACK) && !oonstack &&
! 407: (psp->ps_sigonstack & sigmask(sig))) {
! 408: fp = (struct hpuxsigframe *)(psp->ps_sigstk.ss_sp +
! 409: psp->ps_sigstk.ss_size - fsize);
! 410: psp->ps_sigstk.ss_flags |= SS_ONSTACK;
! 411: } else
! 412: fp = (struct hpuxsigframe *)(frame->f_regs[SP] - fsize);
! 413: if ((unsigned)fp <= USRSTACK - ctob(p->p_vmspace->vm_ssize))
! 414: (void)uvm_grow(p, (unsigned)fp);
! 415:
! 416: #ifdef DEBUG
! 417: if ((hpuxsigdebug & SDB_KSTACK) && p->p_pid == hpuxsigpid)
! 418: printf("hpux_sendsig(%d): sig %d ssp %p usp %p scp %p ft %d\n",
! 419: p->p_pid, sig, &oonstack, fp, &fp->hsf_sc, ft);
! 420: #endif
! 421:
! 422: kfp = (struct hpuxsigframe *)malloc((u_long)fsize, M_TEMP, M_WAITOK);
! 423:
! 424: /*
! 425: * Build the argument list for the signal handler.
! 426: */
! 427: kfp->hsf_signum = bsdtohpuxsig(sig);
! 428: kfp->hsf_code = code;
! 429: kfp->hsf_scp = &fp->hsf_sc;
! 430: kfp->hsf_handler = catcher;
! 431:
! 432: /*
! 433: * Save necessary hardware state. Currently this includes:
! 434: * - general registers
! 435: * - original exception frame (if not a "normal" frame)
! 436: * - FP coprocessor state
! 437: */
! 438: kfp->hsf_sigstate.hss_flags = HSS_USERREGS;
! 439: bcopy((caddr_t)frame->f_regs,
! 440: (caddr_t)kfp->hsf_sigstate.hss_frame.f_regs, sizeof frame->f_regs);
! 441: if (ft >= FMT7) {
! 442: #ifdef DEBUG
! 443: if (ft > 15 || exframesize[ft] < 0)
! 444: panic("hpux_sendsig: bogus frame type");
! 445: #endif
! 446: kfp->hsf_sigstate.hss_flags |= HSS_RTEFRAME;
! 447: kfp->hsf_sigstate.hss_frame.f_format = frame->f_format;
! 448: kfp->hsf_sigstate.hss_frame.f_vector = frame->f_vector;
! 449: bcopy((caddr_t)&frame->F_u,
! 450: (caddr_t)&kfp->hsf_sigstate.hss_frame.F_u, exframesize[ft]);
! 451:
! 452: /*
! 453: * Leave an indicator that we need to clean up the kernel
! 454: * stack. We do this by setting the "pad word" above the
! 455: * hardware stack frame to the amount the stack must be
! 456: * adjusted by.
! 457: *
! 458: * N.B. we increment rather than just set f_stackadj in
! 459: * case we are called from syscall when processing a
! 460: * sigreturn. In that case, f_stackadj may be non-zero.
! 461: */
! 462: frame->f_stackadj += exframesize[ft];
! 463: frame->f_format = frame->f_vector = 0;
! 464: #ifdef DEBUG
! 465: if (hpuxsigdebug & SDB_FOLLOW)
! 466: printf("hpux_sendsig(%d): copy out %d of frame %d\n",
! 467: p->p_pid, exframesize[ft], ft);
! 468: #endif
! 469: }
! 470: if (fputype) {
! 471: kfp->hsf_sigstate.hss_flags |= HSS_FPSTATE;
! 472: m68881_save(&kfp->hsf_sigstate.hss_fpstate);
! 473: }
! 474:
! 475: #ifdef DEBUG
! 476: if ((hpuxsigdebug & SDB_FPSTATE) &&
! 477: *(char *)&kfp->hsf_sigstate.hss_fpstate)
! 478: printf("hpux_sendsig(%d): copy out FP state (%x) to %p\n",
! 479: p->p_pid, *(u_int *)&kfp->hsf_sigstate.hss_fpstate,
! 480: &kfp->hsf_sigstate.hss_fpstate);
! 481: #endif
! 482:
! 483: /*
! 484: * Build the signal context to be used by hpux_sigreturn.
! 485: */
! 486: kfp->hsf_sc.hsc_syscall = 0; /* XXX */
! 487: kfp->hsf_sc.hsc_action = 0; /* XXX */
! 488: kfp->hsf_sc.hsc_pad1 = kfp->hsf_sc.hsc_pad2 = 0;
! 489: kfp->hsf_sc.hsc_onstack = oonstack;
! 490: kfp->hsf_sc.hsc_mask = mask;
! 491: kfp->hsf_sc.hsc_sp = frame->f_regs[SP];
! 492: kfp->hsf_sc.hsc_ps = frame->f_sr;
! 493: kfp->hsf_sc.hsc_pc = frame->f_pc;
! 494:
! 495: /* How amazingly convenient! */
! 496: kfp->hsf_sc._hsc_pad = 0;
! 497: kfp->hsf_sc._hsc_ap = (int)&fp->hsf_sigstate;
! 498:
! 499: if (copyout((caddr_t)kfp, (caddr_t)fp, fsize) != 0) {
! 500: #ifdef DEBUG
! 501: if ((hpuxsigdebug & SDB_KSTACK) && p->p_pid == hpuxsigpid)
! 502: printf("hpux_sendsig(%d): copyout failed on sig %d\n",
! 503: p->p_pid, sig);
! 504: #endif
! 505: /*
! 506: * Process has trashed its stack; give it an illegal
! 507: * instruction to halt it in its tracks.
! 508: */
! 509: free((caddr_t)kfp, M_TEMP);
! 510: sigexit(p, SIGILL);
! 511: /* NOTREACHED */
! 512: }
! 513: frame->f_regs[SP] = (int)fp;
! 514:
! 515: #ifdef DEBUG
! 516: if (hpuxsigdebug & SDB_FOLLOW) {
! 517: printf(
! 518: "hpux_sendsig(%d): sig %d scp %p fp %p sc_sp %x sc_ap %x\n",
! 519: p->p_pid, sig, kfp->hsf_scp, fp,
! 520: kfp->hsf_sc.hsc_sp, kfp->hsf_sc._hsc_ap);
! 521: }
! 522: #endif
! 523:
! 524: /*
! 525: * Signal trampoline code is at base of user stack.
! 526: */
! 527: frame->f_pc = p->p_sigcode;
! 528: #ifdef DEBUG
! 529: if ((hpuxsigdebug & SDB_KSTACK) && p->p_pid == hpuxsigpid)
! 530: printf("hpux_sendsig(%d): sig %d returns\n",
! 531: p->p_pid, sig);
! 532: #endif
! 533: free((caddr_t)kfp, M_TEMP);
! 534: }
! 535:
! 536: /*
! 537: * System call to cleanup state after a signal
! 538: * has been taken. Reset signal mask and
! 539: * stack state from context left by sendsig (above).
! 540: * Return to previous pc and psl as specified by
! 541: * context left by sendsig. Check carefully to
! 542: * make sure that the user has not modified the
! 543: * psl to gain improper privileges or to cause
! 544: * a machine fault.
! 545: */
! 546: /* ARGSUSED */
! 547: int
! 548: hpux_sys_sigreturn(p, v, retval)
! 549: struct proc *p;
! 550: void *v;
! 551: register_t *retval;
! 552: {
! 553: struct hpux_sys_sigreturn_args /* {
! 554: syscallarg(struct hpuxsigcontext *) sigcntxp;
! 555: } */ *uap = v;
! 556: struct hpuxsigcontext *scp;
! 557: struct frame *frame;
! 558: int rf;
! 559: struct hpuxsigcontext tsigc;
! 560: struct hpuxsigstate tstate;
! 561: int flags;
! 562:
! 563: scp = SCARG(uap, sigcntxp);
! 564: #ifdef DEBUG
! 565: if (hpuxsigdebug & SDB_FOLLOW)
! 566: printf("sigreturn: pid %d, scp %p\n", p->p_pid, scp);
! 567: #endif
! 568: if ((int)scp & 1)
! 569: return (EINVAL);
! 570:
! 571: /*
! 572: * Fetch and test the HP-UX context structure.
! 573: * We grab it all at once for speed.
! 574: */
! 575: if (copyin((caddr_t)scp, (caddr_t)&tsigc, sizeof tsigc))
! 576: return (EINVAL);
! 577: scp = &tsigc;
! 578: if ((scp->hsc_ps & PSL_USERCLR) != 0 ||
! 579: (scp->hsc_ps & PSL_USERSET) != PSL_USERSET)
! 580: return (EINVAL);
! 581:
! 582: /*
! 583: * Restore the user supplied information
! 584: */
! 585: if (scp->hsc_onstack & 01)
! 586: p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK;
! 587: else
! 588: p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
! 589: p->p_sigmask = scp->hsc_mask &~ sigcantmask;
! 590: frame = (struct frame *) p->p_md.md_regs;
! 591: frame->f_regs[SP] = scp->hsc_sp;
! 592: frame->f_pc = scp->hsc_pc;
! 593: frame->f_sr = scp->hsc_ps;
! 594:
! 595: /*
! 596: * Grab a pointer to the hpuxsigstate.
! 597: * If zero, the user is probably doing a longjmp.
! 598: * (This will never happen, really, since HP-UX doesn't
! 599: * know/care about the state pointer.)
! 600: */
! 601: if ((rf = scp->_hsc_ap) == 0)
! 602: return (EJUSTRETURN);
! 603:
! 604: /*
! 605: * See if there is anything to do before we go to the
! 606: * expense of copying in close to 1/2K of data
! 607: */
! 608: if (copyin((caddr_t)rf, &flags, sizeof(int)) != 0)
! 609: return (EINVAL);
! 610: #ifdef DEBUG
! 611: if (hpuxsigdebug & SDB_FOLLOW)
! 612: printf("sigreturn(%d): sc_ap %x flags %x\n",
! 613: p->p_pid, rf, flags);
! 614: #endif
! 615: if (flags == 0 || copyin((caddr_t)rf, (caddr_t)&tstate, sizeof tstate))
! 616: return (EJUSTRETURN);
! 617: #ifdef DEBUG
! 618: if ((hpuxsigdebug & SDB_KSTACK) && p->p_pid == hpuxsigpid)
! 619: printf("sigreturn(%d): ssp %p usp %x scp %p ft %d\n",
! 620: p->p_pid, &flags, scp->hsc_sp, SCARG(uap, sigcntxp),
! 621: (flags & HSS_RTEFRAME) ? tstate.hss_frame.f_format : -1);
! 622: #endif
! 623: /*
! 624: * Restore most of the users registers except for A6 and SP
! 625: * which were handled above.
! 626: */
! 627: if (flags & HSS_USERREGS)
! 628: bcopy((caddr_t)tstate.hss_frame.f_regs,
! 629: (caddr_t)frame->f_regs, sizeof(frame->f_regs)-2*NBPW);
! 630:
! 631: /*
! 632: * Restore long stack frames. Note that we do not copy
! 633: * back the saved SR or PC, they were picked up above from
! 634: * the sigcontext structure.
! 635: */
! 636: if (flags & HSS_RTEFRAME) {
! 637: int sz;
! 638:
! 639: /* grab frame type and validate */
! 640: sz = tstate.hss_frame.f_format;
! 641: if (sz > 15 || (sz = exframesize[sz]) < 0)
! 642: return (EINVAL);
! 643: frame->f_stackadj -= sz;
! 644: frame->f_format = tstate.hss_frame.f_format;
! 645: frame->f_vector = tstate.hss_frame.f_vector;
! 646: bcopy((caddr_t)&tstate.hss_frame.F_u,
! 647: (caddr_t)&frame->F_u, sz);
! 648: #ifdef DEBUG
! 649: if (hpuxsigdebug & SDB_FOLLOW)
! 650: printf("sigreturn(%d): copy in %d of frame type %d\n",
! 651: p->p_pid, sz, tstate.hss_frame.f_format);
! 652: #endif
! 653: }
! 654:
! 655: /*
! 656: * Finally we restore the original FP context
! 657: */
! 658: if (flags & HSS_FPSTATE)
! 659: m68881_restore(&tstate.hss_fpstate);
! 660:
! 661: #ifdef DEBUG
! 662: if ((hpuxsigdebug & SDB_FPSTATE) && *(char *)&tstate.hss_fpstate)
! 663: printf("sigreturn(%d): copied in FP state (%x) at %p\n",
! 664: p->p_pid, *(u_int *)&tstate.hss_fpstate,
! 665: &tstate.hss_fpstate);
! 666:
! 667: if ((hpuxsigdebug & SDB_FOLLOW) ||
! 668: ((hpuxsigdebug & SDB_KSTACK) && p->p_pid == hpuxsigpid))
! 669: printf("sigreturn(%d): returns\n", p->p_pid);
! 670: #endif
! 671: return (EJUSTRETURN);
! 672: }
! 673:
! 674: /*
! 675: * Set registers on exec.
! 676: * XXX Should clear registers except sp, pc.
! 677: */
! 678: void
! 679: hpux_setregs(p, pack, stack, retval)
! 680: struct proc *p;
! 681: struct exec_package *pack;
! 682: u_long stack;
! 683: register_t *retval;
! 684: {
! 685: struct frame *frame = (struct frame *)p->p_md.md_regs;
! 686:
! 687: frame->f_pc = pack->ep_entry & ~1;
! 688: frame->f_regs[SP] = stack;
! 689: frame->f_regs[A2] = (int)PS_STRINGS;
! 690:
! 691: /* restore a null state frame */
! 692: p->p_addr->u_pcb.pcb_fpregs.fpf_null = 0;
! 693: if (fputype)
! 694: m68881_restore(&p->p_addr->u_pcb.pcb_fpregs);
! 695:
! 696: p->p_md.md_flags &= ~MDP_HPUXMMAP;
! 697: frame->f_regs[A0] = 0; /* not 68010 (bit 31), no FPA (30) */
! 698: retval[0] = 0; /* no float card */
! 699: if (fputype)
! 700: retval[1] = 1; /* yes 68881 */
! 701: else
! 702: retval[1] = 0; /* no 68881 */
! 703: }
CVSweb