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

Annotation of sys/arch/mvme68k/mvme68k/hpux_machdep.c, Revision 1.1.1.1

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

CVSweb