Annotation of kernel/machdep/ppc/systemcalls.c, revision 1.1.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.