[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

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