[BACK]Return to hpux_machdep.c CVS log [TXT][DIR] Up to [local] / sys / arch / hp300 / hp300

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