Annotation of 43BSDReno/sys/hp300/trap.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1988 University of Utah.
        !             3:  * Copyright (c) 1982, 1986, 1990 The Regents of the University of California.
        !             4:  * All rights reserved.
        !             5:  *
        !             6:  * This code is derived from software contributed to Berkeley by
        !             7:  * the Systems Programming Group of the University of Utah Computer
        !             8:  * Science Department.
        !             9:  *
        !            10:  * Redistribution is only permitted until one year after the first shipment
        !            11:  * of 4.4BSD by the Regents.  Otherwise, redistribution and use in source and
        !            12:  * binary forms are permitted provided that: (1) source distributions retain
        !            13:  * this entire copyright notice and comment, and (2) distributions including
        !            14:  * binaries display the following acknowledgement:  This product includes
        !            15:  * software developed by the University of California, Berkeley and its
        !            16:  * contributors'' in the documentation or other materials provided with the
        !            17:  * distribution and in all advertising materials mentioning features or use
        !            18:  * of this software.  Neither the name of the University nor the names of
        !            19:  * its contributors may be used to endorse or promote products derived from
        !            20:  * this software without specific prior written permission.
        !            21:  * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
        !            22:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
        !            23:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
        !            24:  *
        !            25:  * from: Utah $Hdr: trap.c 1.28 89/09/25$
        !            26:  *
        !            27:  *     @(#)trap.c      7.7 (Berkeley) 6/25/90
        !            28:  */
        !            29: 
        !            30: #include "cpu.h"
        !            31: #include "psl.h"
        !            32: #include "reg.h"
        !            33: #include "pte.h"
        !            34: #include "mtpr.h"
        !            35: 
        !            36: #include "param.h"
        !            37: #include "systm.h"
        !            38: #include "user.h"
        !            39: #include "proc.h"
        !            40: #include "seg.h"
        !            41: #include "trap.h"
        !            42: #include "acct.h"
        !            43: #include "kernel.h"
        !            44: #include "vm.h"
        !            45: #include "cmap.h"
        !            46: #include "syslog.h"
        !            47: #ifdef KTRACE
        !            48: #include "ktrace.h"
        !            49: #endif
        !            50: 
        !            51: #ifdef HPUXCOMPAT
        !            52: #include "../hpux/hpux.h"
        !            53: #endif
        !            54: 
        !            55: #define        USER    040             /* user-mode flag added to type */
        !            56: 
        !            57: struct sysent  sysent[];
        !            58: int    nsysent;
        !            59: 
        !            60: char   *trap_type[] = {
        !            61:        "Bus error",
        !            62:        "Address error",
        !            63:        "Illegal instruction",
        !            64:        "Zero divide",
        !            65:        "CHK instruction",
        !            66:        "TRAPV instruction",
        !            67:        "Privilege violation",
        !            68:        "Trace trap",
        !            69:        "MMU fault",
        !            70:        "SSIR trap",
        !            71:        "Format error",
        !            72:        "68881 exception",
        !            73:        "Coprocessor violation",
        !            74:        "Async system trap"
        !            75: };
        !            76: #define        TRAP_TYPES      (sizeof trap_type / sizeof trap_type[0])
        !            77: 
        !            78: #ifdef DEBUG
        !            79: int mmudebug = 0;
        !            80: #endif
        !            81: 
        !            82: /*
        !            83:  * Called from the trap handler when a processor trap occurs.
        !            84:  */
        !            85: /*ARGSUSED*/
        !            86: trap(type, code, v, frame)
        !            87:        int type;
        !            88:        unsigned code;
        !            89:        register unsigned v;
        !            90:        struct frame frame;
        !            91: {
        !            92:        register int i;
        !            93:        unsigned ucode = 0;
        !            94:        register struct proc *p = u.u_procp;
        !            95:        struct timeval syst;
        !            96:        unsigned ncode;
        !            97: 
        !            98:        cnt.v_trap++;
        !            99:        syst = u.u_ru.ru_stime;
        !           100:        if (USERMODE(frame.f_sr)) {
        !           101:                type |= USER;
        !           102:                u.u_ar0 = frame.f_regs;
        !           103:        }
        !           104:        switch (type) {
        !           105: 
        !           106:        default:
        !           107: dopanic:
        !           108: #ifdef KGDB
        !           109:                if (!panicstr && kgdb_trap(type, code, v, &frame))
        !           110:                        return;
        !           111: #endif
        !           112:                printf("trap type %d, code = %x, v = %x\n", type, code, v);
        !           113:                regdump(frame.f_regs, 128);
        !           114:                type &= ~USER;
        !           115:                if ((unsigned)type < TRAP_TYPES)
        !           116:                        panic(trap_type[type]);
        !           117:                panic("trap");
        !           118: 
        !           119:        case T_BUSERR:          /* kernel bus error */
        !           120:                if (!u.u_pcb.pcb_onfault)
        !           121:                        goto dopanic;
        !           122:                /*
        !           123:                 * If we have arranged to catch this fault in any of the
        !           124:                 * copy to/from user space routines, set PC to return to
        !           125:                 * indicated location and set flag informing buserror code
        !           126:                 * that it may need to clean up stack frame.
        !           127:                 */
        !           128: copyfault:
        !           129:                frame.f_pc = (int) u.u_pcb.pcb_onfault;
        !           130:                frame.f_stackadj = -1;
        !           131:                return;
        !           132: 
        !           133:        case T_BUSERR+USER:     /* bus error */
        !           134:        case T_ADDRERR+USER:    /* address error */
        !           135:                i = SIGBUS;
        !           136:                break;
        !           137: 
        !           138: #ifdef FPCOPROC
        !           139:        case T_COPERR:          /* kernel coprocessor violation */
        !           140: #endif
        !           141:        case T_FMTERR:          /* kernel format error */
        !           142:        /*
        !           143:         * The user has most likely trashed the RTE or FP state info
        !           144:         * in the stack frame of a signal handler.
        !           145:         */
        !           146:                type |= USER;
        !           147:                printf("pid %d: kernel %s exception\n", u.u_procp->p_pid,
        !           148:                       type==T_COPERR ? "coprocessor" : "format");
        !           149:                u.u_signal[SIGILL] = SIG_DFL;
        !           150:                i = sigmask(SIGILL);
        !           151:                p->p_sigignore &= ~i;
        !           152:                p->p_sigcatch &= ~i;
        !           153:                p->p_sigmask &= ~i;
        !           154:                i = SIGILL;
        !           155:                ucode = frame.f_format; /* XXX was ILL_RESAD_FAULT */
        !           156:                break;
        !           157: 
        !           158: #ifdef FPCOPROC
        !           159:        case T_COPERR+USER:     /* user coprocessor violation */
        !           160:        /* What is a proper response here? */
        !           161:                ucode = 0;
        !           162:                i = SIGFPE;
        !           163:                break;
        !           164: 
        !           165:        case T_FPERR+USER:              /* 68881 exceptions */
        !           166:        /*
        !           167:         * We pass along the 68881 status register which locore stashed
        !           168:         * in code for us.  Note that there is a possibility that the
        !           169:         * bit pattern of this register will conflict with one of the
        !           170:         * FPE_* codes defined in signal.h.  Fortunately for us, the
        !           171:         * only such codes we use are all in the range 1-7 and the low
        !           172:         * 3 bits of the status register are defined as 0 so there is
        !           173:         * no clash.
        !           174:         */
        !           175:                ucode = code;
        !           176:                i = SIGFPE;
        !           177:                break;
        !           178: #endif
        !           179: 
        !           180:        case T_ILLINST+USER:    /* illegal instruction fault */
        !           181: #ifdef HPUXCOMPAT
        !           182:                if (u.u_procp->p_flag & SHPUX) {
        !           183:                        ucode = HPUX_ILL_ILLINST_TRAP;
        !           184:                        i = SIGILL;
        !           185:                        break;
        !           186:                }
        !           187:                /* fall through */
        !           188: #endif
        !           189:        case T_PRIVINST+USER:   /* privileged instruction fault */
        !           190: #ifdef HPUXCOMPAT
        !           191:                if (u.u_procp->p_flag & SHPUX)
        !           192:                        ucode = HPUX_ILL_PRIV_TRAP;
        !           193:                else
        !           194: #endif
        !           195:                ucode = frame.f_format; /* XXX was ILL_PRIVIN_FAULT */
        !           196:                i = SIGILL;
        !           197:                break;
        !           198: 
        !           199:        case T_ZERODIV+USER:    /* Divide by zero */
        !           200: #ifdef HPUXCOMPAT
        !           201:                if (u.u_procp->p_flag & SHPUX)
        !           202:                        ucode = HPUX_FPE_INTDIV_TRAP;
        !           203:                else
        !           204: #endif
        !           205:                ucode = frame.f_format; /* XXX was FPE_INTDIV_TRAP */
        !           206:                i = SIGFPE;
        !           207:                break;
        !           208: 
        !           209:        case T_CHKINST+USER:    /* CHK instruction trap */
        !           210: #ifdef HPUXCOMPAT
        !           211:                if (u.u_procp->p_flag & SHPUX) {
        !           212:                        /* handled differently under hp-ux */
        !           213:                        i = SIGILL;
        !           214:                        ucode = HPUX_ILL_CHK_TRAP;
        !           215:                        break;
        !           216:                }
        !           217: #endif
        !           218:                ucode = frame.f_format; /* XXX was FPE_SUBRNG_TRAP */
        !           219:                i = SIGFPE;
        !           220:                break;
        !           221: 
        !           222:        case T_TRAPVINST+USER:  /* TRAPV instruction trap */
        !           223: #ifdef HPUXCOMPAT
        !           224:                if (u.u_procp->p_flag & SHPUX) {
        !           225:                        /* handled differently under hp-ux */
        !           226:                        i = SIGILL;
        !           227:                        ucode = HPUX_ILL_TRAPV_TRAP;
        !           228:                        break;
        !           229:                }
        !           230: #endif
        !           231:                ucode = frame.f_format; /* XXX was FPE_INTOVF_TRAP */
        !           232:                i = SIGFPE;
        !           233:                break;
        !           234: 
        !           235:        /*
        !           236:         * XXX: Trace traps are a nightmare.
        !           237:         *
        !           238:         *      HP-UX uses trap #1 for breakpoints,
        !           239:         *      HPBSD uses trap #2,
        !           240:         *      SUN 3.x uses trap #15,
        !           241:         *      KGDB uses trap #15 (for kernel breakpoints).
        !           242:         *
        !           243:         * HPBSD and HP-UX traps both get mapped by locore.s into T_TRACE.
        !           244:         * SUN 3.x traps get passed through as T_TRAP15 and are not really
        !           245:         * supported yet.  KGDB traps are also passed through as T_TRAP15
        !           246:         * and are not used yet.
        !           247:         */
        !           248:        case T_TRACE:           /* kernel trace trap */
        !           249:        case T_TRAP15:          /* SUN (or KGDB) kernel trace trap */
        !           250: #ifdef KGDB
        !           251:                if (kgdb_trap(type, code, v, &frame))
        !           252:                        return;
        !           253: #endif
        !           254:                frame.f_sr &= ~PSL_T;
        !           255:                i = SIGTRAP;
        !           256:                break;
        !           257: 
        !           258:        case T_TRACE+USER:      /* user trace trap */
        !           259:        case T_TRAP15+USER:     /* SUN user trace trap */
        !           260:                frame.f_sr &= ~PSL_T;
        !           261:                i = SIGTRAP;
        !           262:                break;
        !           263: 
        !           264:        case T_ASTFLT:          /* system async trap, cannot happen */
        !           265:                goto dopanic;
        !           266: 
        !           267:        case T_ASTFLT+USER:     /* user async trap */
        !           268:                astoff();
        !           269:                /*
        !           270:                 * We check for software interrupts first.  This is because
        !           271:                 * they are at a higher level than ASTs, and on a VAX would
        !           272:                 * interrupt the AST.  We assume that if we are processing
        !           273:                 * an AST that we must be at IPL0 so we don't bother to
        !           274:                 * check.  Note that we ensure that we are at least at SIR
        !           275:                 * IPL while processing the SIR.
        !           276:                 */
        !           277:                spl1();
        !           278:                /* fall into... */
        !           279: 
        !           280:        case T_SSIR:            /* software interrupt */
        !           281:        case T_SSIR+USER:
        !           282:                if (ssir & SIR_NET) {
        !           283:                        siroff(SIR_NET);
        !           284:                        cnt.v_soft++;
        !           285:                        netintr();
        !           286:                }
        !           287:                if (ssir & SIR_CLOCK) {
        !           288:                        siroff(SIR_CLOCK);
        !           289:                        cnt.v_soft++;
        !           290:                        softclock((caddr_t)frame.f_pc, (int)frame.f_sr);
        !           291:                }
        !           292:                /*
        !           293:                 * If this was not an AST trap, we are all done.
        !           294:                 */
        !           295:                if (type != T_ASTFLT+USER) {
        !           296:                        cnt.v_trap--;
        !           297:                        return;
        !           298:                }
        !           299:                spl0();
        !           300: #ifndef PROFTIMER
        !           301:                if ((u.u_procp->p_flag&SOWEUPC) && u.u_prof.pr_scale) {
        !           302:                        addupc(frame.f_pc, &u.u_prof, 1);
        !           303:                        u.u_procp->p_flag &= ~SOWEUPC;
        !           304:                }
        !           305: #endif
        !           306:                goto out;
        !           307: 
        !           308:        case T_MMUFLT:          /* kernel mode page fault */
        !           309:                /*
        !           310:                 * Could be caused by a page fault in one of the copy to/from
        !           311:                 * user space routines.  If so, we will have a catch address.
        !           312:                 */
        !           313:                if (!u.u_pcb.pcb_onfault)
        !           314:                        goto dopanic;
        !           315:                /* fall into ... */
        !           316: 
        !           317:        case T_MMUFLT+USER:     /* page fault */
        !           318: /*
        !           319:                printf("trap: T_MMUFLT pid %d, code %x, v %x, pc %x, ps %x\n",
        !           320:                       p->p_pid, code, v, frame.f_pc, frame.f_sr);
        !           321: */
        !           322:                if (v >= USRSTACK) {
        !           323:                        if (type == T_MMUFLT)
        !           324:                                goto copyfault;
        !           325:                        i = SIGSEGV;
        !           326:                        break;
        !           327:                }
        !           328:                ncode = code >> 16;
        !           329: #if defined(HP330) || defined(HP360) || defined(HP370)
        !           330:                /*
        !           331:                 * Crudely map PMMU faults into HP MMU faults.
        !           332:                 */
        !           333:                if (mmutype != MMU_HP) {
        !           334:                        int ocode = ncode;
        !           335:                        ncode = 0;
        !           336:                        if (ocode & PMMU_WP)
        !           337:                                ncode |= MMU_WPF;
        !           338:                        else if (ocode & PMMU_INV) {
        !           339:                                if ((ocode & PMMU_LVLMASK) == 2)
        !           340:                                        ncode |= MMU_PF;
        !           341:                                else 
        !           342:                                        ncode |= MMU_PTF;
        !           343:                        }
        !           344:                        /*
        !           345:                         * RMW cycle, must load ATC by hand
        !           346:                         */
        !           347:                        else if ((code & (SSW_DF|SSW_RM)) == (SSW_DF|SSW_RM)) {
        !           348: #ifdef DEBUG
        !           349:                                log(LOG_WARNING,
        !           350:                                    "RMW fault at %x: MMUSR %x SSW %x\n",
        !           351:                                    v, ocode, code & 0xFFFF);
        !           352: #endif
        !           353:                                ploadw((caddr_t)v);
        !           354:                                return;
        !           355:                        }
        !           356:                        /*
        !           357:                         * Fault with no fault bits, should indicate bad
        !           358:                         * hardware but we see this on 340s using starbase
        !           359:                         * sometimes (faults accessing catseye registers)
        !           360:                         */
        !           361:                        else {
        !           362:                                log(LOG_WARNING,
        !           363:                                    "Bad PMMU fault at %x: MMUSR %x SSW %x\n",
        !           364:                                    v, ocode, code & 0xFFFF);
        !           365:                                return;
        !           366:                        }
        !           367: #ifdef DEBUG
        !           368:                        if (mmudebug && mmudebug == p->p_pid)
        !           369:                                printf("MMU %d: v%x, os%x, ns%x\n",
        !           370:                                       p->p_pid, v, ocode, ncode);
        !           371: #endif
        !           372:                }
        !           373: #endif
        !           374: #ifdef DEBUG
        !           375:                if ((ncode & (MMU_PTF|MMU_PF|MMU_WPF|MMU_FPE)) == 0) {
        !           376:                        printf("T_MMUFLT with no fault bits\n");
        !           377:                        goto dopanic;
        !           378:                }
        !           379: #endif
        !           380:                if (ncode & MMU_PTF) {
        !           381: #ifdef DEBUG
        !           382:                        /*
        !           383:                         * NOTE: we use a u_int instead of an ste since the
        !           384:                         * current compiler generates bogus code for some
        !           385:                         * bitfield operations (i.e. attempts to access last
        !           386:                         * word of a page as a longword causing fault).
        !           387:                         */
        !           388:                        extern struct ste *vtoste();
        !           389:                        u_int *ste = (u_int *)vtoste(p, v);
        !           390: 
        !           391:                        if (*ste & SG_V) {
        !           392:                                if (ncode & MMU_WPF) {
        !           393:                                        printf("PTF|WPF...\n");
        !           394:                                        if (type == T_MMUFLT)
        !           395:                                                goto copyfault;
        !           396:                                        i = SIGBUS;
        !           397:                                        break;
        !           398:                                }
        !           399:                                printf("MMU_PTF with sg_v, ste@%x = %x\n",
        !           400:                                       ste, *ste);
        !           401:                                goto dopanic;
        !           402:                        }
        !           403: #endif
        !           404: #ifdef HPUXCOMPAT
        !           405:                        if (ISHPMMADDR(v)) {
        !           406:                                extern struct ste *vtoste();
        !           407:                                u_int *bste, *nste;
        !           408: 
        !           409:                                bste = (u_int *)vtoste(p, HPMMBASEADDR(v));
        !           410:                                nste = (u_int *)vtoste(p, v);
        !           411:                                if ((*bste & SG_V) && *nste == SG_NV) {
        !           412:                                        *nste = *bste;
        !           413:                                        TBIAU();
        !           414:                                        return;
        !           415:                                }
        !           416:                        }
        !           417: #endif
        !           418:                growit:
        !           419:                        if (type == T_MMUFLT)
        !           420:                                goto copyfault;
        !           421:                        if (grow((unsigned)frame.f_regs[SP]) || grow(v))
        !           422:                                goto out;
        !           423:                        i = SIGSEGV;
        !           424:                        break;
        !           425:                }
        !           426: #ifdef HPUXCOMPAT
        !           427:                if (ISHPMMADDR(v)) {
        !           428:                        TBIS(v);
        !           429:                        v = HPMMBASEADDR(v);
        !           430:                }
        !           431: #endif
        !           432:                /*
        !           433:                 * NOTE: WPF without PG_V is possible
        !           434:                 * (e.g. attempt to write shared text which is paged out)
        !           435:                 */
        !           436:                if (ncode & MMU_WPF) {
        !           437: #ifdef DEBUG
        !           438:                        extern struct ste *vtoste();
        !           439:                        u_int *ste = (u_int *)vtoste(p, v);
        !           440: 
        !           441:                        if (!(*ste & SG_V)) {
        !           442:                                printf("MMU_WPF without sg_v, ste@%x = %x\n",
        !           443:                                       ste, *ste);
        !           444:                                goto dopanic;
        !           445:                        }
        !           446: #endif
        !           447:                        if (type == T_MMUFLT)
        !           448:                                goto copyfault;
        !           449:                        i = SIGBUS;
        !           450:                        break;
        !           451:                }
        !           452:                if (ncode & MMU_PF) {
        !           453:                        register u_int vp;
        !           454: #ifdef DEBUG
        !           455:                        extern struct ste *vtoste();
        !           456:                        u_int *ste = (u_int *)vtoste(p, v);
        !           457:                        struct pte *pte;
        !           458: 
        !           459:                        if (!(*ste & SG_V)) {
        !           460:                                printf("MMU_PF without sg_v, ste@%x = %x\n",
        !           461:                                       ste, *ste);
        !           462:                                goto dopanic;
        !           463:                        }
        !           464: #endif
        !           465:                        vp = btop(v);
        !           466:                        if (vp >= dptov(p, p->p_dsize) &&
        !           467:                            vp < sptov(p, p->p_ssize-1))
        !           468:                                goto growit;
        !           469: #ifdef DEBUG
        !           470:                        pte = vtopte(p, vp);
        !           471:                        if (*(u_int *)pte & PG_V) {
        !           472:                                printf("MMU_PF with pg_v, pte = %x\n",
        !           473:                                       *(u_int *)pte);
        !           474:                                goto dopanic;
        !           475:                        }
        !           476: #endif
        !           477:                        pagein(v, 0);
        !           478:                        if (type == T_MMUFLT)
        !           479:                                return;
        !           480:                        goto out;
        !           481:                }
        !           482: #ifdef DEBUG
        !           483:                printf("T_MMUFLT: unrecognized scenerio\n");
        !           484:                goto dopanic;
        !           485: #endif
        !           486:        }
        !           487:        trapsignal(i, ucode);
        !           488:        if ((type & USER) == 0)
        !           489:                return;
        !           490: out:
        !           491:        p = u.u_procp;
        !           492:        if (i = CURSIG(p))
        !           493:                psig(i);
        !           494:        p->p_pri = p->p_usrpri;
        !           495:        if (runrun) {
        !           496:                /*
        !           497:                 * Since we are u.u_procp, clock will normally just change
        !           498:                 * our priority without moving us from one queue to another
        !           499:                 * (since the running process is not on a queue.)
        !           500:                 * If that happened after we setrq ourselves but before we
        !           501:                 * swtch()'ed, we might not be on the queue indicated by
        !           502:                 * our priority.
        !           503:                 */
        !           504:                (void) splclock();
        !           505:                setrq(p);
        !           506:                u.u_ru.ru_nivcsw++;
        !           507:                swtch();
        !           508:                if (i = CURSIG(p))
        !           509:                        psig(i);
        !           510:        }
        !           511:        if (u.u_prof.pr_scale) {
        !           512:                int ticks;
        !           513:                struct timeval *tv = &u.u_ru.ru_stime;
        !           514: 
        !           515:                ticks = ((tv->tv_sec - syst.tv_sec) * 1000 +
        !           516:                        (tv->tv_usec - syst.tv_usec) / 1000) / (tick / 1000);
        !           517:                if (ticks) {
        !           518: #ifdef PROFTIMER
        !           519:                        extern int profscale;
        !           520:                        addupc(frame.f_pc, &u.u_prof, ticks * profscale);
        !           521: #else
        !           522:                        addupc(frame.f_pc, &u.u_prof, ticks);
        !           523: #endif
        !           524:                }
        !           525:        }
        !           526:        curpri = p->p_pri;
        !           527: }
        !           528: 
        !           529: /*
        !           530:  * Called from the trap handler when a system call occurs
        !           531:  */
        !           532: /*ARGSUSED*/
        !           533: syscall(code, frame)
        !           534:        volatile int code;
        !           535:        struct frame frame;
        !           536: {
        !           537:        register caddr_t params;
        !           538:        register int i;
        !           539:        register struct sysent *callp;
        !           540:        register struct proc *p = u.u_procp;
        !           541:        int error, opc, numsys;
        !           542:        struct args {
        !           543:                int i[8];
        !           544:        } args;
        !           545:        int rval[2];
        !           546:        struct timeval syst;
        !           547:        struct sysent *systab;
        !           548: #ifdef HPUXCOMPAT
        !           549:        extern struct sysent hpuxsysent[];
        !           550:        extern int hpuxnsysent, notimp();
        !           551: #endif
        !           552: 
        !           553:        cnt.v_syscall++;
        !           554:        syst = u.u_ru.ru_stime;
        !           555:        if (!USERMODE(frame.f_sr))
        !           556:                panic("syscall");
        !           557:        u.u_ar0 = frame.f_regs;
        !           558:        opc = frame.f_pc - 2;
        !           559:        systab = sysent;
        !           560:        numsys = nsysent;
        !           561: #ifdef HPUXCOMPAT
        !           562:        if (p->p_flag & SHPUX) {
        !           563:                systab = hpuxsysent;
        !           564:                numsys = hpuxnsysent;
        !           565:        }
        !           566: #endif
        !           567:        params = (caddr_t)frame.f_regs[SP] + NBPW;
        !           568:        if (code == 0) {                        /* indir */
        !           569:                code = fuword(params);
        !           570:                params += NBPW;
        !           571:        }
        !           572:        if (code >= numsys)
        !           573:                callp = &systab[0];             /* indir (illegal) */
        !           574:        else
        !           575:                callp = &systab[code];
        !           576:        if ((i = callp->sy_narg * sizeof (int)) &&
        !           577:            (error = copyin(params, (caddr_t)&args, (u_int)i))) {
        !           578: #ifdef HPUXCOMPAT
        !           579:                if (p->p_flag & SHPUX)
        !           580:                        error = bsdtohpuxerrno(error);
        !           581: #endif
        !           582:                frame.f_regs[D0] = (u_char) error;
        !           583:                frame.f_sr |= PSL_C;    /* carry bit */
        !           584: #ifdef KTRACE
        !           585:                if (KTRPOINT(p, KTR_SYSCALL))
        !           586:                        ktrsyscall(p->p_tracep, code, callp->sy_narg, args.i);
        !           587: #endif
        !           588:                goto done;
        !           589:        }
        !           590: #ifdef KTRACE
        !           591:        if (KTRPOINT(p, KTR_SYSCALL))
        !           592:                ktrsyscall(p->p_tracep, code, callp->sy_narg, args.i);
        !           593: #endif
        !           594:        rval[0] = 0;
        !           595:        rval[1] = frame.f_regs[D1];
        !           596: #ifdef HPUXCOMPAT
        !           597:        /* debug kludge */
        !           598:        if (callp->sy_call == notimp)
        !           599:                error = notimp(u.u_procp, args.i, rval, code, callp->sy_narg);
        !           600:        else
        !           601: #endif
        !           602:        error = (*callp->sy_call)(u.u_procp, &args, rval);
        !           603:        if (error == ERESTART)
        !           604:                frame.f_pc = opc;
        !           605:        else if (error != EJUSTRETURN) {
        !           606:                if (error) {
        !           607: #ifdef HPUXCOMPAT
        !           608:                        if (p->p_flag & SHPUX)
        !           609:                                error = bsdtohpuxerrno(error);
        !           610: #endif
        !           611:                        frame.f_regs[D0] = (u_char) error;
        !           612:                        frame.f_sr |= PSL_C;    /* carry bit */
        !           613:                } else {
        !           614:                        frame.f_regs[D0] = rval[0];
        !           615:                        frame.f_regs[D1] = rval[1];
        !           616:                        frame.f_sr &= ~PSL_C;
        !           617:                }
        !           618:        }
        !           619:        /* else if (error == EJUSTRETURN) */
        !           620:                /* nothing to do */
        !           621: 
        !           622: done:
        !           623:        /*
        !           624:         * Reinitialize proc pointer `p' as it may be different
        !           625:         * if this is a child returning from fork syscall.
        !           626:         */
        !           627:        p = u.u_procp;
        !           628:        /*
        !           629:         * XXX the check for sigreturn ensures that we don't
        !           630:         * attempt to set up a call to a signal handler (sendsig) before
        !           631:         * we have cleaned up the stack from the last call (sigreturn).
        !           632:         * Allowing this seems to lock up the machine in certain scenarios.
        !           633:         * What should really be done is to clean up the signal handling
        !           634:         * so that this is not a problem.
        !           635:         */
        !           636: #include "syscall.h"
        !           637:        if (code != SYS_sigreturn && (i = CURSIG(p)))
        !           638:                psig(i);
        !           639:        p->p_pri = p->p_usrpri;
        !           640:        if (runrun) {
        !           641:                /*
        !           642:                 * Since we are u.u_procp, clock will normally just change
        !           643:                 * our priority without moving us from one queue to another
        !           644:                 * (since the running process is not on a queue.)
        !           645:                 * If that happened after we setrq ourselves but before we
        !           646:                 * swtch()'ed, we might not be on the queue indicated by
        !           647:                 * our priority.
        !           648:                 */
        !           649:                (void) splclock();
        !           650:                setrq(p);
        !           651:                u.u_ru.ru_nivcsw++;
        !           652:                swtch();
        !           653:                if (code != SYS_sigreturn && (i = CURSIG(p)))
        !           654:                        psig(i);
        !           655:        }
        !           656:        if (u.u_prof.pr_scale) {
        !           657:                int ticks;
        !           658:                struct timeval *tv = &u.u_ru.ru_stime;
        !           659: 
        !           660:                ticks = ((tv->tv_sec - syst.tv_sec) * 1000 +
        !           661:                        (tv->tv_usec - syst.tv_usec) / 1000) / (tick / 1000);
        !           662:                if (ticks) {
        !           663: #ifdef PROFTIMER
        !           664:                        extern int profscale;
        !           665:                        addupc(frame.f_pc, &u.u_prof, ticks * profscale);
        !           666: #else
        !           667:                        addupc(frame.f_pc, &u.u_prof, ticks);
        !           668: #endif
        !           669:                }
        !           670:        }
        !           671:        curpri = p->p_pri;
        !           672: #ifdef KTRACE
        !           673:        if (KTRPOINT(p, KTR_SYSRET))
        !           674:                ktrsysret(p->p_tracep, code, error, rval[0]);
        !           675: #endif
        !           676: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.