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/powerpc/powerpc/copyinout.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) 2002 Benno Rice
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  *
   14  * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR
   15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   17  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   18  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
   20  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
   21  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
   22  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
   23  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   24 */
   25 /*-
   26  * Copyright (C) 1993 Wolfgang Solfrank.
   27  * Copyright (C) 1993 TooLs GmbH.
   28  * All rights reserved.
   29  *
   30  * Redistribution and use in source and binary forms, with or without
   31  * modification, are permitted provided that the following conditions
   32  * are met:
   33  * 1. Redistributions of source code must retain the above copyright
   34  *    notice, this list of conditions and the following disclaimer.
   35  * 2. Redistributions in binary form must reproduce the above copyright
   36  *    notice, this list of conditions and the following disclaimer in the
   37  *    documentation and/or other materials provided with the distribution.
   38  * 3. All advertising materials mentioning features or use of this software
   39  *    must display the following acknowledgement:
   40  *      This product includes software developed by TooLs GmbH.
   41  * 4. The name of TooLs GmbH may not be used to endorse or promote products
   42  *    derived from this software without specific prior written permission.
   43  *
   44  * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
   45  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   46  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   47  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   48  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   49  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
   50  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
   51  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
   52  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
   53  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   54  */
   55 
   56 #ifndef lint
   57 static const char rcsid[] =
   58   "$FreeBSD: releng/5.0/sys/powerpc/powerpc/copyinout.c 98480 2002-06-20 07:13:35Z peter $";
   59 #endif /* not lint */
   60 
   61 #include <sys/param.h>
   62 #include <sys/systm.h>
   63 #include <sys/proc.h>
   64 
   65 #include <vm/vm.h>
   66 #include <vm/pmap.h>
   67 #include <vm/vm_map.h>
   68 
   69 int     setfault(faultbuf);     /* defined in locore.S */
   70 
   71 /*
   72  * Makes sure that the right segment of userspace is mapped in.
   73  */
   74 static __inline void
   75 set_user_sr(register_t vsid)
   76 {
   77 
   78         isync();
   79         __asm __volatile ("mtsr %0,%1" :: "n"(USER_SR), "r"(vsid));
   80         isync();
   81 }
   82 
   83 int
   84 copyout(const void *kaddr, void *udaddr, size_t len)
   85 {
   86         struct          thread *td;
   87         pmap_t          pm;
   88         faultbuf        env;
   89         const char      *kp;
   90         char            *up, *p;
   91         size_t          l;
   92 
   93         td = PCPU_GET(curthread);
   94         pm = &td->td_proc->p_vmspace->vm_pmap;
   95 
   96         if (setfault(env)) {
   97                 td->td_pcb->pcb_onfault = NULL;
   98                 return (EFAULT);
   99         }
  100 
  101         kp = kaddr;
  102         up = udaddr;
  103 
  104         while (len > 0) {
  105                 p = (char *)USER_ADDR + ((u_int)up & ~SEGMENT_MASK);
  106 
  107                 l = ((char *)USER_ADDR + SEGMENT_LENGTH) - p;
  108                 if (l > len)
  109                         l = len;
  110 
  111                 set_user_sr(pm->pm_sr[(u_int)up >> ADDR_SR_SHFT]);
  112 
  113                 bcopy(kp, p, l);
  114 
  115                 up += l;
  116                 kp += l;
  117                 len -= l;
  118         }
  119 
  120         td->td_pcb->pcb_onfault = NULL;
  121         return (0);
  122 }
  123 
  124 int
  125 copyin(const void *udaddr, void *kaddr, size_t len)
  126 {
  127         struct          thread *td;
  128         pmap_t          pm;
  129         faultbuf        env;
  130         const char      *up;
  131         char            *kp, *p;
  132         size_t          l;
  133 
  134         td = PCPU_GET(curthread);
  135         pm = &td->td_proc->p_vmspace->vm_pmap;
  136 
  137         if (setfault(env)) {
  138                 td->td_pcb->pcb_onfault = NULL;
  139                 return (EFAULT);
  140         }
  141 
  142         kp = kaddr;
  143         up = udaddr;
  144 
  145         while (len > 0) {
  146                 p = (char *)USER_ADDR + ((u_int)up & ~SEGMENT_MASK);
  147 
  148                 l = ((char *)USER_ADDR + SEGMENT_LENGTH) - p;
  149                 if (l > len)
  150                         l = len;
  151 
  152                 set_user_sr(pm->pm_sr[(u_int)up >> ADDR_SR_SHFT]);
  153 
  154                 bcopy(p, kp, l);
  155 
  156                 up += l;
  157                 kp += l;
  158                 len -= l;
  159         }
  160 
  161         td->td_pcb->pcb_onfault = NULL;
  162         return (0);
  163 }
  164 
  165 int
  166 copyinstr(const void *udaddr, void *kaddr, size_t len, size_t *done)
  167 {
  168         struct          thread *td;
  169         pmap_t          pm;
  170         faultbuf        env;
  171         const char      *up;
  172         char            *kp;
  173         size_t          l;
  174         int             rv, c;
  175 
  176         td = PCPU_GET(curthread);
  177         pm = &td->td_proc->p_vmspace->vm_pmap;
  178 
  179         if (setfault(env)) {
  180                 td->td_pcb->pcb_onfault = NULL;
  181                 return (EFAULT);
  182         }
  183 
  184         kp = kaddr;
  185         up = udaddr;
  186 
  187         rv = ENAMETOOLONG;
  188 
  189         for (l = 0; len-- > 0; l++) {
  190                 if ((c = fubyte(up++)) < 0) {
  191                         rv = EFAULT;
  192                         break;
  193                 }
  194 
  195                 if (!(*kp++ = c)) {
  196                         l++;
  197                         rv = 0;
  198                         break;
  199                 }
  200         }
  201 
  202         if (done != NULL) {
  203                 *done = l;
  204         }
  205 
  206         td->td_pcb->pcb_onfault = NULL;
  207         return (rv);
  208 }
  209 
  210 int
  211 subyte(void *addr, int byte)
  212 {
  213         struct          thread *td;
  214         pmap_t          pm;
  215         faultbuf        env;
  216         char            *p;
  217 
  218         td = PCPU_GET(curthread);
  219         pm = &td->td_proc->p_vmspace->vm_pmap;
  220         p = (char *)((u_int)USER_ADDR + ((u_int)addr & ~SEGMENT_MASK));
  221 
  222         if (setfault(env)) {
  223                 td->td_pcb->pcb_onfault = NULL;
  224                 return (EFAULT);
  225         }
  226 
  227         set_user_sr(pm->pm_sr[(u_int)addr >> ADDR_SR_SHFT]);
  228 
  229         *p = (char)byte;
  230 
  231         td->td_pcb->pcb_onfault = NULL;
  232         return (0);
  233 }
  234 
  235 int
  236 suword(void *addr, long word)
  237 {
  238         struct          thread *td;
  239         pmap_t          pm;
  240         faultbuf        env;
  241         long            *p;
  242 
  243         td = PCPU_GET(curthread);
  244         pm = &td->td_proc->p_vmspace->vm_pmap;
  245         p = (long *)((u_int)USER_ADDR + ((u_int)addr & ~SEGMENT_MASK));
  246 
  247         if (setfault(env)) {
  248                 td->td_pcb->pcb_onfault = NULL;
  249                 return (EFAULT);
  250         }
  251 
  252         set_user_sr(pm->pm_sr[(u_int)addr >> ADDR_SR_SHFT]);
  253 
  254         *p = word;
  255 
  256         td->td_pcb->pcb_onfault = NULL;
  257         return (0);
  258 }
  259 
  260 int
  261 suword32(void *addr, int32_t word)
  262 {
  263         return (suword(addr, (long)word));
  264 }
  265 
  266 
  267 int
  268 fubyte(const void *addr)
  269 {
  270         struct          thread *td;
  271         pmap_t          pm;
  272         faultbuf        env;
  273         char            *p;
  274         int             val;
  275 
  276         td = PCPU_GET(curthread);
  277         pm = &td->td_proc->p_vmspace->vm_pmap;
  278         p = (char *)((u_int)USER_ADDR + ((u_int)addr & ~SEGMENT_MASK));
  279 
  280         if (setfault(env)) {
  281                 td->td_pcb->pcb_onfault = NULL;
  282                 return (EFAULT);
  283         }
  284 
  285         set_user_sr(pm->pm_sr[(u_int)addr >> ADDR_SR_SHFT]);
  286 
  287         val = (int)*p;
  288 
  289         td->td_pcb->pcb_onfault = NULL;
  290         return (val);
  291 }
  292 
  293 long
  294 fuword(const void *addr)
  295 {
  296         struct          thread *td;
  297         pmap_t          pm;
  298         faultbuf        env;
  299         long            *p, val;
  300 
  301         td = PCPU_GET(curthread);
  302         pm = &td->td_proc->p_vmspace->vm_pmap;
  303         p = (long *)((u_int)USER_ADDR + ((u_int)addr & ~SEGMENT_MASK));
  304 
  305         if (setfault(env)) {
  306                 td->td_pcb->pcb_onfault = NULL;
  307                 return (EFAULT);
  308         }
  309 
  310         set_user_sr(pm->pm_sr[(u_int)addr >> ADDR_SR_SHFT]);
  311 
  312         val = *p;
  313 
  314         td->td_pcb->pcb_onfault = NULL;
  315         return (val);
  316 }
  317 
  318 int32_t
  319 fuword32(const void *addr)
  320 {
  321         return ((int32_t)fuword(addr));
  322 }

Cache object: 85838c0147328b67701d8f628596b6ee


[ 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.