]>
git.saurik.com Git - apple/xnu.git/blob - bsd/dev/ppc/mem.c
   2  * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved. 
   4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 
   6  * This file contains Original Code and/or Modifications of Original Code 
   7  * as defined in and that are subject to the Apple Public Source License 
   8  * Version 2.0 (the 'License'). You may not use this file except in 
   9  * compliance with the License. The rights granted to you under the License 
  10  * may not be used to create, or enable the creation or redistribution of, 
  11  * unlawful or unlicensed copies of an Apple operating system, or to 
  12  * circumvent, violate, or enable the circumvention or violation of, any 
  13  * terms of an Apple operating system software license agreement. 
  15  * Please obtain a copy of the License at 
  16  * http://www.opensource.apple.com/apsl/ and read it before using this file. 
  18  * The Original Code and all software distributed under the License are 
  19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 
  22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  23  * Please see the License for the specific language governing rights and 
  24  * limitations under the License. 
  26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 
  29  * Copyright (c) 1988 University of Utah. 
  30  * Copyright (c) 1982, 1986, 1990, 1993 
  31  *      The Regents of the University of California.  All rights reserved. 
  33  * This code is derived from software contributed to Berkeley by 
  34  * the Systems Programming Group of the University of Utah Computer 
  35  * Science Department, and code derived from software contributed to 
  36  * Berkeley by William Jolitz. 
  38  * Redistribution and use in source and binary forms, with or without 
  39  * modification, are permitted provided that the following conditions 
  41  * 1. Redistributions of source code must retain the above copyright 
  42  *    notice, this list of conditions and the following disclaimer. 
  43  * 2. Redistributions in binary form must reproduce the above copyright 
  44  *    notice, this list of conditions and the following disclaimer in the 
  45  *    documentation and/or other materials provided with the distribution. 
  46  * 3. All advertising materials mentioning features or use of this software 
  47  *    must display the following acknowledgement: 
  48  *      This product includes software developed by the University of 
  49  *      California, Berkeley and its contributors. 
  50  * 4. Neither the name of the University nor the names of its contributors 
  51  *    may be used to endorse or promote products derived from this software 
  52  *    without specific prior written permission. 
  54  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 
  55  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
  56  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
  57  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 
  58  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
  59  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
  60  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
  61  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
  62  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
  63  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
  66  * from: Utah $Hdr: mem.c 1.13 89/10/08$ 
  67  *      @(#)mem.c       8.1 (Berkeley) 6/11/93 
  70 #include <mach_load.h> 
  76 #include <sys/param.h> 
  79 #include <sys/systm.h> 
  81 #include <sys/uio_internal.h> 
  82 #include <sys/malloc.h> 
  85 #include <vm/vm_map.h> 
  86 #include <vm/vm_kern.h> 
  87 #include <mach/vm_param.h> 
  89 #include <ppc/Diagnostics.h> 
  90 #include <ppc/mappings.h> 
  92 static caddr_t devzerobuf
; 
  94 extern pmap_t kernel_pmap
; 
  95 extern boolean_t 
kernacc(off_t
, size_t ); 
  97 int mmread(dev_t dev
, struct uio 
*uio
); 
  98 int mmrw(dev_t dev
, struct uio 
*uio
, enum uio_rw rw
); 
  99 int mmioctl(dev_t dev
, u_long cmd
, caddr_t data
, int flag
, struct proc 
*p
); 
 100 int mmwrite(dev_t dev
, struct uio 
*uio
); 
 108         return (mmrw(dev
, uio
, UIO_READ
)); 
 117         return (mmrw(dev
, uio
, UIO_WRITE
)); 
 121 mmioctl(__unused dev_t dev
, u_long cmd
, __unused caddr_t data
,  
 122                 __unused 
int flag
, __unused 
struct proc 
*p
) 
 127                 /* OK to do nothing: we always return immediately */ 
 152         while (uio_resid(uio
) > 0 && error 
== 0) { 
 153                 if (uio_iov_len(uio
) == 0) { 
 156                         if (uio
->uio_iovcnt 
< 0) 
 160                 switch (minor(dev
)) { 
 162 /* minor device 0 is physical memory */ 
 164                         vll 
= trunc_page_64(uio
->uio_offset
); 
 165                         if(((vll 
>> 31) == 1) || vll 
>= ((dgWork
.dgFlags 
& enaDiagDM
) ? mem_actual 
: max_mem
)) 
 168                         if(dgWork
.dgFlags 
& enaDiagDM
) {                        /* Can we really get all memory? */ 
 169                                 if (kmem_alloc_pageable(kernel_map
, &where
, PAGE_SIZE
) != KERN_SUCCESS
) { 
 175                                         collad 
= mapping_make(kernel_pmap
, (addr64_t
)where
, (ppnum_t
)(vll 
>> 12), 0, 1, VM_PROT_READ
);  /* Map it in for the moment */ 
 176                                         if(collad
) {                                            /* See if it failed (shouldn't happen)  */ 
 177                                                 kmem_free(kernel_map
, where
, PAGE_SIZE
);        /* Toss the page */ 
 178                                                 goto fault
;                                             /* Kill the transfer */ 
 183                                 if (kmem_alloc(kernel_map
, &where
, 4096)  
 188                         o 
= uio
->uio_offset 
- vll
; 
 189                         // LP64todo - fix this! 
 190                         c 
= min(PAGE_SIZE 
- o
, uio_iov_len(uio
)); 
 191                         error 
= uiomove((caddr_t
)(where 
+ o
), c
, uio
); 
 193                         if(dgWork
.dgFlags 
& enaDiagDM
) (void)mapping_remove(kernel_pmap
, (addr64_t
)where
);      /* Unmap it */ 
 194                         kmem_free(kernel_map
, where
, PAGE_SIZE
); 
 197                 /* minor device 1 is kernel memory */ 
 199                         /* Do some sanity checking */ 
 200                         if (((addr64_t
)uio
->uio_offset 
> vm_last_addr
) || 
 201                                 ((addr64_t
)uio
->uio_offset 
< VM_MIN_KERNEL_ADDRESS
)) 
 203                         c 
= uio_iov_len(uio
); 
 204                         if (!kernacc(uio
->uio_offset
, c
)) 
 206                         error 
= uiomove64(uio
->uio_offset
, c
, uio
); 
 209                 /* minor device 2 is EOF/RATHOLE */ 
 213                         c 
= uio_iov_len(uio
); 
 215                 /* minor device 3 is ZERO/RATHOLE */ 
 217                         if(devzerobuf 
== NULL
) { 
 218                                 MALLOC(devzerobuf
, caddr_t
,PAGE_SIZE
, M_TEMP
, M_WAITOK
); 
 219                                 bzero(devzerobuf
, PAGE_SIZE
); 
 221                         if(uio
->uio_rw 
== UIO_WRITE
) { 
 222                                 c 
= uio_iov_len(uio
); 
 225                         // LP64todo - fix this! 
 226                         c 
= min(uio_iov_len(uio
), PAGE_SIZE
); 
 227                         error 
= uiomove(devzerobuf
, c
, uio
); 
 236                 uio_iov_base_add(uio
, c
); 
 237                 uio
->uio_offset 
+= c
; 
 239                 uio_setresid(uio
, (uio_resid(uio
) - c
)); 
 240                 uio_iov_len_add(uio
, -((int64_t)c
)); 
 242                 uio_setresid(uio
, (uio_resid(uio
) - c
)); 
 243                 uio_iov_len_add(uio
, -((int)c
));