Annotation of kernel/machdep/ppc/systemcalls.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
        !             7:  * Reserved.  This file contains Original Code and/or Modifications of
        !             8:  * Original Code as defined in and that are subject to the Apple Public
        !             9:  * Source License Version 1.1 (the "License").  You may not use this file
        !            10:  * except in compliance with the License.  Please obtain a copy of the
        !            11:  * License at http://www.apple.com/publicsource and read it before using
        !            12:  * this file.
        !            13:  * 
        !            14:  * The Original Code and all software distributed under the License are
        !            15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
        !            19:  * License for the specific language governing rights and limitations
        !            20:  * under the License.
        !            21:  * 
        !            22:  * @APPLE_LICENSE_HEADER_END@
        !            23:  */
        !            24: 
        !            25: /*
        !            26:  * Copyright (c) 1997 Apple Computer, Inc.
        !            27:  *
        !            28:  * PowerPC Family:     System Call handlers.
        !            29:  *
        !            30:  * HISTORY
        !            31:  * 18-Aug-97   Umesh Vaishampayan  ([email protected])
        !            32:  *     Added syscalltrace filtering. 
        !            33:  * 27-July-97  Umesh Vaishampayan  ([email protected])
        !            34:  *     Debug printf() changed to kprintf(). Cleanup unused system timing.
        !            35:  */
        !            36:  
        !            37: #include <mach/mach_types.h>
        !            38: #include <mach/exception.h>
        !            39: #include <mach/error.h>
        !            40: 
        !            41: #include <kern/syscall_sw.h>
        !            42: #include <kern/kdp.h>
        !            43: #include <kern/kdebug.h>
        !            44: 
        !            45: #include <machdep/ppc/frame.h>
        !            46: #include <machdep/ppc/thread.h>
        !            47: #include <machdep/ppc/asm.h>
        !            48: #include <machdep/ppc/proc_reg.h>
        !            49: #include <machdep/ppc/trap.h>
        !            50: #include <machdep/ppc/exception.h>
        !            51: #include <machdep/ppc/pcb_flags.h>
        !            52: 
        !            53: #include <sys/param.h>
        !            54: #include <sys/proc.h>
        !            55: #include <sys/user.h>
        !            56: #include <sys/systm.h>
        !            57: 
        !            58: #if DIAGNOSTIC
        !            59: /* syscalltrace defines */
        !            60: #define _SCT_NUM_PIDS  8
        !            61: 
        !            62: #define _SCT_OFF       0x00
        !            63: #define        _SCT_MACHCALLS  0x01
        !            64: #define        _SCT_UNIXCALLS  0x02
        !            65: #define        _SCT_ALL        (_SCT_MACHCALLS | _SCT_UNIXCALLS)
        !            66: 
        !            67: int syscalltrace = 0;
        !            68: int usepids = 0;               /* 1 enables pid filtering */
        !            69: int pidstraced[_SCT_NUM_PIDS]; /* can specify upto _SCT_NUM_PIDS to filter */
        !            70: 
        !            71: static int
        !            72: matchpid( int pid )
        !            73: {
        !            74:        int i;
        !            75:        for(i=0; i<_SCT_NUM_PIDS; i++)
        !            76:                if( pidstraced[i] == pid )
        !            77:                        return 1; /* match! */
        !            78:        return 0; /* not found */
        !            79: }
        !            80: 
        !            81: #endif /* DIAGNOSTIC */
        !            82: 
        !            83: /*
        !            84: ** Function:   mach_syscall
        !            85: **
        !            86: ** Inputs:     pcb     - pointer to Process Control Block
        !            87: **             arg1    - arguments to mach system calls
        !            88: **             arg2
        !            89: **             arg3
        !            90: **             arg4
        !            91: **             arg5
        !            92: **             arg6
        !            93: **             arg7
        !            94: **
        !            95: ** Outputs:    none
        !            96: **
        !            97: ** Notes:      There may be additional arguments to the mach calls
        !            98: **             that will be read in from user space if necessary
        !            99: */
        !           100: void
        !           101: mach_syscall(
        !           102:     struct pcb * pcb,
        !           103:     int arg1,
        !           104:     int arg2,
        !           105:     int arg3,
        !           106:     int arg4,
        !           107:     int arg5,
        !           108:     int arg6,
        !           109:     int arg7
        !           110:     )
        !           111: {
        !           112:     struct ppc_saved_state     *regs;
        !           113:     int                                error;  /* error code */
        !           114:     struct uthread             *uthread;
        !           115:     struct proc                        *p;
        !           116:     
        !           117:     /* the mach trap number supplied by libmach */
        !           118:     int                                mach_trap;
        !           119:     mach_trap_t                        *trapp;
        !           120:     thread_t                   thread;
        !           121:     int                                arg0;
        !           122:     struct stack_frame         *usfp;
        !           123:     int                                sbargs[4], uasfp, *argp;
        !           124:     extern char                        *mach_callnames[];  
        !           125: 
        !           126: 
        !           127:     if (!USERMODE(pcb->ss.srr1))
        !           128:        panic("mach_syscall");
        !           129: 
        !           130:     regs = &pcb->ss;
        !           131: 
        !           132:     thread = current_thread();
        !           133:     uthread = thread->_uthread;
        !           134:     uthread->uu_ar0 = (int *)pcb;
        !           135:     p = current_proc();
        !           136: 
        !           137:     /* get the mach trap number */
        !           138:     mach_trap = -(regs->r0);
        !           139: 
        !           140:     /* get the first argument to the mach trap call */
        !           141:     arg0 = regs->r3;
        !           142: 
        !           143:     error = 0;
        !           144: 
        !           145:     /* find mach trap table entry */
        !           146:     if (mach_trap >= mach_trap_count  ||  mach_trap < 0)
        !           147:     {
        !           148:        error = KERN_FAILURE;
        !           149:     }
        !           150:     else
        !           151:     {
        !           152:        trapp = &mach_trap_table[mach_trap];
        !           153: 
        !           154:        if (trapp->mach_trap_arg_count > MAXREGARGS)
        !           155:        {
        !           156:            int i, word;
        !           157: 
        !           158:            /*
        !           159:            **  This code gets executed when there are more than MAXREGARGS
        !           160:            ** worth of parameters expected for the call.  The additional
        !           161:            ** parameters are passed on the users stack and must be copies
        !           162:            ** in from user space.
        !           163:            */
        !           164:            if (trapp->mach_trap_arg_count > NARGS)
        !           165:                panic("mach_syscall: max arg count exceeded");
        !           166: 
        !           167:            /* get the user stack frame pointer from saved state r1 */
        !           168:            usfp = (struct stack_frame *)regs->r1;
        !           169: 
        !           170:            /* set up a pointer to the user arguments stack frame pointer */
        !           171:            uasfp = (int)&usfp->pa.spa.saved_p8;
        !           172: 
        !           173:            /* setup the pointer for the stack based args */
        !           174:            argp = sbargs;
        !           175: 
        !           176:            for (i = 0; i < (trapp->mach_trap_arg_count - MAXREGARGS); i++ )
        !           177:            {
        !           178:                if (copyin ((void *)uasfp++, (void *)&word, sizeof(int)))
        !           179:                {
        !           180:                    regs->r3 = -1;
        !           181:                    thread_exception_return();
        !           182:                }
        !           183:                *argp++ = word;
        !           184:            }
        !           185:        }
        !           186: 
        !           187: #if DIAGNOSTIC
        !           188:        if ((syscalltrace == _SCT_MACHCALLS) || (syscalltrace == _SCT_ALL)) {
        !           189:                int trpid = ((p) ? p->p_pid : -1);
        !           190:                if((!usepids) || (usepids && matchpid(trpid)))
        !           191:                        kprintf("%s (%d) mach_syscall[%d = %s] --",
        !           192:                        ((p) ? p->p_comm : "no-proc"),
        !           193:                        trpid, mach_trap, mach_callnames[mach_trap]);
        !           194:        }
        !           195: #endif /* DIAGNOSTIC */
        !           196:        /*
        !           197:        ** Notice that there are always NARGS passed into the mach_trap
        !           198:        ** regardless whether they are needed or not.
        !           199:        **
        !           200:        ** If NARGS changes this function call must be changed as well!!
        !           201:        */
        !           202:        KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_EXCP_SC, 0) | DBG_FUNC_START,
        !           203:                                             mach_trap, arg0, arg1, arg2, arg3);
        !           204: 
        !           205:        error = (*(trapp->mach_trap_function))( arg0, arg1,
        !           206:                                                arg2, arg3,
        !           207:                                                arg4, arg5,
        !           208:                                                arg6, arg7,
        !           209:                                                sbargs[0], sbargs[1],
        !           210:                                                sbargs[2], sbargs[3] );
        !           211: 
        !           212:        KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_EXCP_SC, 0) | DBG_FUNC_END,
        !           213:                                             mach_trap, error, 0, 0, 0);
        !           214: #if DIAGNOSTIC
        !           215:        if ((syscalltrace == _SCT_MACHCALLS) || (syscalltrace == _SCT_ALL)) {
        !           216:                int trpid = ((p) ? p->p_pid : -1);
        !           217:                if((!usepids) || (usepids && matchpid(trpid))) {
        !           218:                        if (error)
        !           219:                                kprintf("> sys=0x%X, sub=0x%X, code=0x%X\n",
        !           220:                                err_get_system(error), err_get_sub(error),
        !           221:                                err_get_code(error));
        !           222:                        else
        !           223:                                kprintf("> error == 0x%X\n", error);
        !           224:                }
        !           225:        }
        !           226: #endif /* DIAGNOSTIC */
        !           227:     }
        !           228: 
        !           229:     regs->r3 = error;
        !           230: 
        !           231:     thread_exception_return();
        !           232:     /* NOTREACHED */
        !           233: }
        !           234: 
        !           235: 
        !           236: /*
        !           237: ** Function:   unix_syscall
        !           238: **
        !           239: ** Inputs:     pcb     - pointer to Process Control Block
        !           240: **             arg1    - arguments to mach system calls
        !           241: **             arg2
        !           242: **             arg3
        !           243: **             arg4
        !           244: **             arg5
        !           245: **             arg6
        !           246: **             arg7
        !           247: **
        !           248: ** Outputs:    none
        !           249: */
        !           250: void
        !           251: unix_syscall(
        !           252:     struct pcb * pcb,
        !           253:     int arg1,
        !           254:     int arg2,
        !           255:     int arg3,
        !           256:     int arg4,
        !           257:     int arg5,
        !           258:     int arg6,
        !           259:     int arg7 
        !           260:     )
        !           261: {
        !           262:     struct ppc_saved_state     *regs;
        !           263:     thread_t                   thread;
        !           264:     struct uthread             *uthread;
        !           265:     struct sysent              *callp;
        !           266:     struct proc                        *p;
        !           267:     int                                nargs, error;
        !           268:     unsigned short             code;
        !           269:     int                                rval[2];
        !           270:     extern char *syscallnames[];  
        !           271: 
        !           272:     if (!USERMODE(pcb->ss.srr1))
        !           273:        panic("unix_syscall");
        !           274: 
        !           275:     regs = &pcb->ss;
        !           276:     thread = current_thread();
        !           277: 
        !           278:     uthread = thread->_uthread;
        !           279:     uthread->uu_ar0 = (int *)pcb;
        !           280:     p = current_proc();
        !           281: 
        !           282:     /*
        !           283:     ** Get index into sysent table
        !           284:     */   
        !           285:     code = regs->r0;
        !           286: 
        !           287:     if (code > nsysent)
        !           288:     {
        !           289:        error = 0;
        !           290:        switch (code) {
        !           291:        case 0x7FFA:
        !           292:          if ((thread->pcb->flags & PCB_BB_MASK) == 0) {
        !           293:             error = EPERM;
        !           294:             break;
        !           295:          }
        !           296:          NotifyInterruption(regs->r3,arg1,arg2,arg3,arg4,arg5,arg6,arg7);
        !           297:          break;
        !           298:        case 0x7FFF:
        !           299:            mapBlueBoxShmem(regs->r3,arg1,arg2,arg3,arg4,arg5,arg6,arg7);
        !           300:            break;
        !           301:        case 0x7FFD:
        !           302:            unmapBlueBoxShmem(regs->r3,arg1,arg2,arg3,arg4,arg5,arg6,arg7);
        !           303:            break;
        !           304:        }
        !           305:     }
        !           306:     else {
        !           307:        /*
        !           308:        ** Set up call pointer
        !           309:        */
        !           310:        callp = (code >= nsysent) ? &sysent[63] : &sysent[code];
        !           311: 
        !           312:        /*
        !           313:        ** SPECIAL CASE function 0 to be indirect system call
        !           314:        */
        !           315:        if (callp == sysent)
        !           316:        {
        !           317:        code = regs->r3;
        !           318:        callp = (code >= nsysent) ? &sysent[63] : &sysent[code];
        !           319:        uthread->uu_arg[0] = arg1;
        !           320:        uthread->uu_arg[1] = arg2;
        !           321:        uthread->uu_arg[2] = arg3;
        !           322:        uthread->uu_arg[3] = arg4;
        !           323:        uthread->uu_arg[4] = arg5;
        !           324:        uthread->uu_arg[5] = arg6;
        !           325:        uthread->uu_arg[6] = arg7;
        !           326:        }
        !           327:        else
        !           328:        {
        !           329:        /*
        !           330:        ** Set up the args for the system call
        !           331:        */ 
        !           332:        uthread->uu_arg[0] = regs->r3; 
        !           333:        uthread->uu_arg[1] = arg1;
        !           334:        uthread->uu_arg[2] = arg2;
        !           335:        uthread->uu_arg[3] = arg3;
        !           336:        uthread->uu_arg[4] = arg4;
        !           337:        uthread->uu_arg[5] = arg5;
        !           338:        uthread->uu_arg[6] = arg6;
        !           339:        uthread->uu_arg[7] = arg7;
        !           340:        }
        !           341: 
        !           342:        if (callp->sy_narg > 8)
        !           343:        panic("unix_syscall: max arg count exceeded");
        !           344: 
        !           345:        rval[0] = 0;
        !           346: 
        !           347:        /* r4 is volatile, if we set it to regs->r4 here the child
        !           348:         * will have parents r4 after execve */
        !           349:        rval[1] = 0;
        !           350: 
        !           351:        error = 0; /* Start with a good value */
        !           352: 
        !           353:        /*
        !           354:        ** the PPC runtime calls cerror after every unix system call, so
        !           355:        ** assume no error and adjust the "pc" to skip this call.
        !           356:        ** It will be set back to the cerror call if an error is detected.
        !           357:        */
        !           358:        regs->srr0 += 4;
        !           359: #if DIAGNOSTIC
        !           360:        if ((syscalltrace == _SCT_UNIXCALLS) || (syscalltrace == _SCT_ALL)) {
        !           361:                int trpid = ((p) ? p->p_pid : -1);
        !           362:                if((!usepids) || (usepids && matchpid(trpid))) {
        !           363:                        kprintf("%s(%d) unix_syscall[%d = %s] --",
        !           364:                        ((p) ? p->p_comm : "no-proc"),
        !           365:                        trpid, code, syscallnames[code]);
        !           366:                        if ( (code == 5) || (code == 59) )
        !           367:                                kprintf(" arg0 = %x, arg1 = %d, arg2 = %d, "
        !           368:                                "arg3 = %d --",
        !           369:                                uthread->uu_arg[0], uthread->uu_arg[1],
        !           370:                                uthread->uu_arg[2], uthread->uu_arg[3]);
        !           371:                }
        !           372:        }
        !           373: #endif /* DIAGNOSTIC */
        !           374: #if KDEBUG
        !           375:        if (code != 180) {
        !           376:                KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_EXCP_SC, 1) | DBG_FUNC_START,
        !           377:                                             code, uthread->uu_arg[0], uthread->uu_arg[1],
        !           378:                                                   uthread->uu_arg[2], uthread->uu_arg[3]);
        !           379:        }
        !           380: #endif /* KDEBUG */
        !           381: 
        !           382:        error = (*(callp->sy_call))(p, (caddr_t)uthread->uu_arg, rval);
        !           383: 
        !           384: #if KDEBUG
        !           385:        if (code != 180) {
        !           386:                KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_EXCP_SC, 1) | DBG_FUNC_END,
        !           387:                                             code, error, rval[0], rval[1], 0);
        !           388:        }
        !           389: #endif /* KDEBUG */
        !           390: #if DIAGNOSTIC
        !           391:        if ((syscalltrace == _SCT_UNIXCALLS) || (syscalltrace == _SCT_ALL)) {
        !           392:                int trpid = ((p) ? p->p_pid : -1);
        !           393:                if((!usepids) || (usepids && matchpid(trpid)))
        !           394:                        if (error)
        !           395:                                kprintf("> error == 0x%X\n", error);
        !           396:                        else
        !           397:                                kprintf("> rval=0x%X %X\n", rval[0],rval[1]);
        !           398:        }
        !           399: #endif /* DIAGNOSTIC */
        !           400:     }
        !           401:     if (error == ERESTART) {
        !           402:        regs->srr0 -= 8;
        !           403:     }
        !           404:     else if (error != EJUSTRETURN) {
        !           405:        if (error)
        !           406:        {
        !           407:            regs->r3 = error;
        !           408:            /* set the "pc" to execute cerror routine */
        !           409:            regs->srr0 -= 4;
        !           410:        } else { /* (not error) */
        !           411:            regs->r3 = rval[0];
        !           412:            regs->r4 = rval[1];
        !           413:        } 
        !           414:     }
        !           415:     /* else  (error == EJUSTRETURN) { nothing } */
        !           416: 
        !           417:     thread_exception_return();
        !           418:     /* NOTREACHED */
        !           419:        
        !           420: }
        !           421: 

unix.superglobalmegacorp.com

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