Annotation of XNU/osfmk/ppc/bsd_ppc.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * The contents of this file constitute Original Code as defined in and
        !             7:  * are subject to the Apple Public Source License Version 1.1 (the
        !             8:  * "License").  You may not use this file except in compliance with the
        !             9:  * License.  Please obtain a copy of the License at
        !            10:  * http://www.apple.com/publicsource and read it before using this file.
        !            11:  * 
        !            12:  * This Original Code and all software distributed under the License are
        !            13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
        !            17:  * License for the specific language governing rights and limitations
        !            18:  * under the License.
        !            19:  * 
        !            20:  * @APPLE_LICENSE_HEADER_END@
        !            21:  */
        !            22: #include <mach/mach_types.h>
        !            23: #include <mach/exception_types.h>
        !            24: #include <mach/error.h>
        !            25: #include <kern/counters.h>
        !            26: #include <kern/syscall_sw.h>
        !            27: #include <kern/task.h>
        !            28: #include <kern/thread.h>
        !            29: #include <ppc/thread.h>
        !            30: #include <kern/thread_act.h>
        !            31: #include <ppc/thread_act.h>
        !            32: #include <ppc/asm.h>
        !            33: #include <ppc/proc_reg.h>
        !            34: #include <ppc/trap.h>
        !            35: #include <ppc/exception.h>
        !            36: #include <kern/assert.h>
        !            37: 
        !            38: #include <sys/kdebug.h>
        !            39: 
        !            40: #define        ERESTART        -1              /* restart syscall */
        !            41: #define        EJUSTRETURN     -2              /* don't modify regs, just return */
        !            42: 
        !            43: struct unix_syscallargs {
        !            44:        int flavor;
        !            45:        int r3;
        !            46:        int arg1, arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9;
        !            47: };
        !            48: struct sysent {                /* system call table */
        !            49:        unsigned short          sy_narg;                /* number of args */
        !            50:        unsigned short          sy_parallel;    /* can execute in parallel */
        !            51:        unsigned long           (*sy_call)(void *, void *, int *);      /* implementing function */
        !            52: };
        !            53: 
        !            54: extern struct sysent sysent[];
        !            55: 
        !            56: void  *get_bsdtask_info(
        !            57:        task_t);
        !            58: 
        !            59: int set_bsduthreadargs (
        !            60:        thread_act_t, struct pcb *, 
        !            61:        struct unix_syscallargs  *);
        !            62: 
        !            63: void * get_bsduthreadarg(
        !            64:        thread_act_t);
        !            65: 
        !            66: void
        !            67: unix_syscall(
        !            68:        struct pcb * pcb,
        !            69:     int, int, int, int, int, int, int );
        !            70: 
        !            71: /*
        !            72:  * Function:   unix_syscall
        !            73:  *
        !            74:  * Inputs:     pcb     - pointer to Process Control Block
        !            75:  *             arg1    - arguments to mach system calls
        !            76:  *             arg2
        !            77:  *             arg3
        !            78:  *             arg4
        !            79:  *             arg5
        !            80:  *             arg6
        !            81:  *             arg7
        !            82:  *
        !            83:  * Outputs:    none
        !            84:  */
        !            85: void
        !            86: unix_syscall(
        !            87:     struct pcb * pcb,
        !            88:     int arg1,
        !            89:     int arg2,
        !            90:     int arg3,
        !            91:     int arg4,
        !            92:     int arg5,
        !            93:     int arg6,
        !            94:     int arg7 
        !            95:     )
        !            96: {
        !            97:     struct ppc_saved_state     *regs;
        !            98:     thread_act_t               thread;
        !            99:     struct sysent              *callp;
        !           100:     int                                nargs, error;
        !           101:     unsigned short             code;
        !           102:     void *  p, *vt;
        !           103:     int * vtint;
        !           104:        int *rval;
        !           105: 
        !           106:        struct unix_syscallargs sarg;
        !           107:        extern int nsysent;
        !           108: 
        !           109:     (void) thread_set_funneled(TRUE);
        !           110: 
        !           111:     regs = &pcb->ss;
        !           112:     thread = current_act();
        !           113:        p = get_bsdtask_info(current_task());
        !           114:        rval = (int *)get_bsduthreadrval(thread);
        !           115: 
        !           116:     /*
        !           117:     ** Get index into sysent table
        !           118:     */   
        !           119:     code = regs->r0;
        !           120: 
        !           121:     
        !           122:        /*
        !           123:        ** Set up call pointer
        !           124:        */
        !           125:        callp = (code >= nsysent) ? &sysent[63] : &sysent[code];
        !           126: 
        !           127:        sarg. flavor = (callp == sysent)? 1: 0;
        !           128:        if (sarg.flavor) {
        !           129:                code = regs->r3;
        !           130:                callp = (code >= nsysent) ? &sysent[63] : &sysent[code];
        !           131: 
        !           132:        }
        !           133:        else 
        !           134:                sarg. r3 = regs->r3;
        !           135:        sarg. arg1 = arg1;
        !           136:        sarg. arg2 = arg2;
        !           137:        sarg. arg3 = arg3;
        !           138:        sarg. arg4 = arg4;
        !           139:        sarg. arg5 = arg5;
        !           140:        sarg. arg6 = arg6;
        !           141:        sarg. arg7 = arg7;
        !           142: 
        !           143:        set_bsduthreadargs(thread,pcb,&sarg);
        !           144: 
        !           145: 
        !           146:        if (callp->sy_narg > 8)
        !           147:        panic("unix_syscall: max arg count exceeded");
        !           148: 
        !           149:        rval[0] = 0;
        !           150: 
        !           151:        /* r4 is volatile, if we set it to regs->r4 here the child
        !           152:         * will have parents r4 after execve */
        !           153:        rval[1] = 0;
        !           154: 
        !           155:        error = 0; /* Start with a good value */
        !           156: 
        !           157:        /*
        !           158:        ** the PPC runtime calls cerror after every unix system call, so
        !           159:        ** assume no error and adjust the "pc" to skip this call.
        !           160:        ** It will be set back to the cerror call if an error is detected.
        !           161:        */
        !           162:        regs->srr0 += 4;
        !           163:        vt = get_bsduthreadarg(thread);
        !           164: 
        !           165:        if (code != 180) {
        !           166:          vtint = (int *) vt;
        !           167:          KERNEL_DEBUG_CONSTANT(BSDDBG_CODE(DBG_BSD_EXCP_SC, code) | DBG_FUNC_START,
        !           168:               vtint[0],vtint[1], vtint[2], vtint[3], 0);
        !           169:        }
        !           170:        
        !           171:        counter_always(c_syscalls_unix++);
        !           172:        current_task()->syscalls_unix++;
        !           173:        error = (*(callp->sy_call))(p, (void *)vt, rval);
        !           174: 
        !           175:        if (code != 180) {
        !           176:          KERNEL_DEBUG_CONSTANT(BSDDBG_CODE(DBG_BSD_EXCP_SC, code) | DBG_FUNC_END,
        !           177:                       error, rval[0], rval[1], 0, 0);
        !           178:        }
        !           179: 
        !           180:     if (error == ERESTART) {
        !           181:        regs->srr0 -= 8;
        !           182:     }
        !           183:     else if (error != EJUSTRETURN) {
        !           184:        if (error)
        !           185:        {
        !           186:            regs->r3 = error;
        !           187:            /* set the "pc" to execute cerror routine */
        !           188:            regs->srr0 -= 4;
        !           189:        } else { /* (not error) */
        !           190:            regs->r3 = rval[0];
        !           191:            regs->r4 = rval[1];
        !           192:        } 
        !           193:     }
        !           194:     /* else  (error == EJUSTRETURN) { nothing } */
        !           195: 
        !           196:     (void) thread_set_funneled(FALSE);
        !           197: 
        !           198:     thread_exception_return();
        !           199:     /* NOTREACHED */
        !           200: }
        !           201: 
        !           202: unix_syscall_return(error)
        !           203: {
        !           204:     struct ppc_saved_state     *regs;
        !           205:     thread_act_t               thread;
        !           206:     struct sysent              *callp;
        !           207:     int                                nargs;
        !           208:     unsigned short             code;
        !           209:        int *rval;
        !           210:    void *  p, *vt;
        !           211:     int * vtint;
        !           212:        struct pcb *pcb;
        !           213: 
        !           214:        struct unix_syscallargs sarg;
        !           215:        extern int nsysent;
        !           216: 
        !           217:     thread = current_act();
        !           218:        p = get_bsdtask_info(current_task());
        !           219:        rval = (int *)get_bsduthreadrval(thread);
        !           220:        pcb = thread->mact.pcb;
        !           221:     regs = &pcb->ss;
        !           222: 
        !           223:     /*
        !           224:     ** Get index into sysent table
        !           225:     */   
        !           226:     code = regs->r0;
        !           227: 
        !           228:        if (code != 180) {
        !           229:          KERNEL_DEBUG_CONSTANT(BSDDBG_CODE(DBG_BSD_EXCP_SC, code) | DBG_FUNC_END,
        !           230:                       error, rval[0], rval[1], 0, 0);
        !           231:        }
        !           232: 
        !           233:     if (error == ERESTART) {
        !           234:        regs->srr0 -= 8;
        !           235:     }
        !           236:     else if (error != EJUSTRETURN) {
        !           237:        if (error)
        !           238:        {
        !           239:            regs->r3 = error;
        !           240:            /* set the "pc" to execute cerror routine */
        !           241:            regs->srr0 -= 4;
        !           242:        } else { /* (not error) */
        !           243:            regs->r3 = rval[0];
        !           244:            regs->r4 = rval[1];
        !           245:        } 
        !           246:     }
        !           247:     /* else  (error == EJUSTRETURN) { nothing } */
        !           248: 
        !           249:     (void) thread_set_funneled(FALSE);
        !           250: 
        !           251:     thread_exception_return();
        !           252:     /* NOTREACHED */
        !           253: }

unix.superglobalmegacorp.com

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