The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/bsd/dev/ppc/systemcalls.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved.
    3  *
    4  * @APPLE_LICENSE_HEADER_START@
    5  * 
    6  * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved.
    7  * 
    8  * This file contains Original Code and/or Modifications of Original Code
    9  * as defined in and that are subject to the Apple Public Source License
   10  * Version 2.0 (the 'License'). You may not use this file except in
   11  * compliance with the License. Please obtain a copy of the License at
   12  * http://www.opensource.apple.com/apsl/ and read it before using this
   13  * file.
   14  * 
   15  * The Original Code and all software distributed under the License are
   16  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
   17  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
   18  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
   19  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
   20  * Please see the License for the specific language governing rights and
   21  * limitations under the License.
   22  * 
   23  * @APPLE_LICENSE_HEADER_END@
   24  */
   25 
   26 #include <kern/task.h>
   27 #include <kern/thread.h>
   28 #include <kern/thread_act.h>
   29 #include <kern/assert.h>
   30 #include <kern/clock.h>
   31 #include <mach/machine/thread_status.h>
   32 #include <ppc/savearea.h>
   33 
   34 #include <sys/kernel.h>
   35 #include <sys/vm.h>
   36 #include <sys/proc.h>
   37 #include <sys/syscall.h>
   38 #include <sys/systm.h>
   39 #include <sys/user.h>
   40 #include <sys/errno.h>
   41 #include <sys/ktrace.h>
   42 #include <sys/kdebug.h>
   43 #include <sys/kern_audit.h>
   44 
   45 extern void
   46 unix_syscall(
   47         struct savearea *regs
   48 );
   49 
   50 extern struct savearea * 
   51 find_user_regs(
   52         thread_act_t act);
   53 
   54 extern void enter_funnel_section(funnel_t *funnel_lock);
   55 extern void exit_funnel_section(void);
   56 
   57 /*
   58  * Function:    unix_syscall
   59  *
   60  * Inputs:      regs    - pointer to Process Control Block
   61  *
   62  * Outputs:     none
   63  */
   64 void
   65 unix_syscall(
   66         struct savearea *regs
   67 )
   68 {
   69         thread_act_t            thread_act;
   70         struct uthread          *uthread;
   71         struct proc                     *proc;
   72         struct sysent           *callp;
   73         int                                     error;
   74         unsigned short          code;
   75         boolean_t                       flavor;
   76         int funnel_type;
   77 
   78         flavor = (((unsigned int)regs->save_r0) == NULL)? 1: 0;
   79 
   80         if (flavor)
   81                 code = regs->save_r3;
   82         else
   83                 code = regs->save_r0;
   84 
   85         if (kdebug_enable && (code != 180)) {
   86                 if (flavor)
   87                         KERNEL_DEBUG_CONSTANT(BSDDBG_CODE(DBG_BSD_EXCP_SC, code) | DBG_FUNC_START,
   88                                 regs->save_r4, regs->save_r5, regs->save_r6, regs->save_r7, 0);
   89                 else
   90                         KERNEL_DEBUG_CONSTANT(BSDDBG_CODE(DBG_BSD_EXCP_SC, code) | DBG_FUNC_START,
   91                                 regs->save_r3, regs->save_r4, regs->save_r5, regs->save_r6, 0);
   92         }
   93         thread_act = current_act();
   94         uthread = get_bsdthread_info(thread_act);
   95 
   96         if (!(uthread->uu_flag & P_VFORK))
   97                 proc = (struct proc *)get_bsdtask_info(current_task());
   98         else
   99                 proc = current_proc();
  100 
  101         uthread->uu_ar0 = (int *)regs;
  102 
  103         callp = (code >= nsysent) ? &sysent[63] : &sysent[code];
  104 
  105 #ifdef  DEBUG
  106         if (callp->sy_narg > 8)
  107                 panic("unix_syscall: max arg count exceeded");
  108 #endif
  109 
  110         if (callp->sy_narg != 0) {
  111                 if ( !flavor) {
  112                         uthread->uu_arg[0] = regs->save_r3;
  113                         uthread->uu_arg[1] = regs->save_r4;
  114                         uthread->uu_arg[2] = regs->save_r5;
  115                         uthread->uu_arg[3] = regs->save_r6;
  116                         uthread->uu_arg[4] = regs->save_r7;
  117                         uthread->uu_arg[5] = regs->save_r8;
  118                         uthread->uu_arg[6] = regs->save_r9;
  119                         uthread->uu_arg[7] = regs->save_r10;
  120                 } else {
  121                         uthread->uu_arg[0] = regs->save_r4;
  122                         uthread->uu_arg[1] = regs->save_r5;
  123                         uthread->uu_arg[2] = regs->save_r6;
  124                         uthread->uu_arg[3] = regs->save_r7;
  125                         uthread->uu_arg[4] = regs->save_r8;
  126                         uthread->uu_arg[5] = regs->save_r9;
  127                         uthread->uu_arg[7] = regs->save_r10;
  128                 }
  129         }
  130 
  131         funnel_type = (int)callp->sy_funnel;
  132         if (funnel_type == KERNEL_FUNNEL) 
  133                  enter_funnel_section(kernel_flock);
  134         else if (funnel_type == NETWORK_FUNNEL)
  135                  enter_funnel_section(network_flock);
  136         
  137         uthread->uu_rval[0] = 0;
  138 
  139         /*
  140          * r4 is volatile, if we set it to regs->save_r4 here the child
  141          * will have parents r4 after execve
  142          */
  143         uthread->uu_rval[1] = 0;
  144 
  145         error = 0;
  146 
  147         /*
  148          * PPC runtime calls cerror after every unix system call, so
  149          * assume no error and adjust the "pc" to skip this call.
  150          * It will be set back to the cerror call if an error is detected.
  151          */
  152         regs->save_srr0 += 4;
  153 
  154         if (KTRPOINT(proc, KTR_SYSCALL))
  155                 ktrsyscall(proc, code, callp->sy_narg, uthread->uu_arg, funnel_type);
  156 
  157         AUDIT_CMD(audit_syscall_enter(code, proc, uthread));
  158         error = (*(callp->sy_call))(proc, (void *)uthread->uu_arg, &(uthread->uu_rval[0]));
  159         AUDIT_CMD(audit_syscall_exit(error, proc, uthread));
  160 
  161         regs = find_user_regs(thread_act);
  162 
  163         if (error == ERESTART) {
  164                 regs->save_srr0 -= 8;
  165         } else if (error != EJUSTRETURN) {
  166                 if (error) {
  167                         regs->save_r3 = (long long)error;
  168                         /* set the "pc" to execute cerror routine */
  169                         regs->save_srr0 -= 4;
  170                 } else { /* (not error) */
  171                         regs->save_r3 = uthread->uu_rval[0];
  172                         regs->save_r4 = uthread->uu_rval[1];
  173                 } 
  174         }
  175         /* else  (error == EJUSTRETURN) { nothing } */
  176 
  177         if (KTRPOINT(proc, KTR_SYSRET))
  178                 ktrsysret(proc, code, error, uthread->uu_rval[0], funnel_type);
  179 
  180          exit_funnel_section();
  181 
  182         if (kdebug_enable && (code != 180)) {
  183                 KERNEL_DEBUG_CONSTANT(BSDDBG_CODE(DBG_BSD_EXCP_SC, code) | DBG_FUNC_END,
  184                         error, uthread->uu_rval[0], uthread->uu_rval[1], 0, 0);
  185         }
  186 
  187         thread_exception_return();
  188         /* NOTREACHED */
  189 }
  190 
  191 unix_syscall_return(error)
  192 {
  193         thread_act_t                            thread_act;
  194         struct uthread                          *uthread;
  195         struct proc                                     *proc;
  196         struct savearea                         *regs;
  197         unsigned short                          code;
  198         struct sysent                           *callp;
  199         int funnel_type;
  200 
  201         thread_act = current_act();
  202         proc = current_proc();
  203         uthread = get_bsdthread_info(thread_act);
  204 
  205         regs = find_user_regs(thread_act);
  206 
  207         /*
  208          * Get index into sysent table
  209          */   
  210         if (error == ERESTART) {
  211                 regs->save_srr0 -= 8;
  212         } else if (error != EJUSTRETURN) {
  213                 if (error) {
  214                         regs->save_r3 = (long long)error;
  215                         /* set the "pc" to execute cerror routine */
  216                         regs->save_srr0 -= 4;
  217                 } else { /* (not error) */
  218                         regs->save_r3 = uthread->uu_rval[0];
  219                         regs->save_r4 = uthread->uu_rval[1];
  220                 } 
  221         }
  222         /* else  (error == EJUSTRETURN) { nothing } */
  223 
  224         if (regs->save_r0 != NULL)
  225                 code = regs->save_r0;
  226         else
  227                 code = regs->save_r3;
  228 
  229         callp = (code >= nsysent) ? &sysent[63] : &sysent[code];
  230 
  231         funnel_type = (int)callp->sy_funnel;
  232 
  233         if (KTRPOINT(proc, KTR_SYSRET))
  234                 ktrsysret(proc, code, error, uthread->uu_rval[0], funnel_type);
  235 
  236          exit_funnel_section();
  237 
  238         if (kdebug_enable && (code != 180)) {
  239                 KERNEL_DEBUG_CONSTANT(BSDDBG_CODE(DBG_BSD_EXCP_SC, code) | DBG_FUNC_END,
  240                         error, uthread->uu_rval[0], uthread->uu_rval[1], 0, 0);
  241         }
  242 
  243         thread_exception_return();
  244         /* NOTREACHED */
  245 }
  246 
  247 /* 
  248  * Time of day and interval timer support.
  249  *
  250  * These routines provide the kernel entry points to get and set
  251  * the time-of-day and per-process interval timers.  Subroutines
  252  * here provide support for adding and subtracting timeval structures
  253  * and decrementing interval timers, optionally reloading the interval
  254  * timers when they expire.
  255  */
  256 struct gettimeofday_args{
  257         struct timeval *tp;
  258         struct timezone *tzp;
  259 };
  260 /*  NOTE THIS implementation is for  ppc architectures only.
  261  *  It is infrequently called, since the commpage intercepts
  262  *  most calls in user mode.
  263  */
  264 int
  265 ppc_gettimeofday(p, uap, retval)
  266         struct proc *p;
  267         register struct gettimeofday_args *uap;
  268         register_t *retval;
  269 {
  270         int error = 0;
  271 
  272         if (uap->tp)
  273                 clock_gettimeofday(&retval[0], &retval[1]);
  274         
  275         if (uap->tzp) {
  276                 struct timezone ltz;
  277                 extern simple_lock_data_t tz_slock;
  278 
  279                 usimple_lock(&tz_slock);
  280                 ltz = tz;
  281                 usimple_unlock(&tz_slock);
  282                 error = copyout((caddr_t)&ltz, (caddr_t)uap->tzp, sizeof (tz));
  283         }
  284 
  285         return (error);
  286 }
  287 

Cache object: b46aaee262f2076f4458e39fe8b4ada6


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.