[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     ! 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