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/osfmk/ppc/io_map.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 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 /*
   23  * @OSF_COPYRIGHT@
   24  * 
   25  */
   26 
   27 #include <debug.h>
   28 #include <mach/vm_param.h>
   29 #include <vm/vm_kern.h>
   30 #include <vm/vm_map.h>
   31 #include <vm/vm_page.h>
   32 #include <ppc/pmap.h>
   33 #include <ppc/io_map_entries.h>
   34 #include <ppc/Firmware.h>
   35 #include <ppc/mappings.h>
   36 #include <ppc/proc_reg.h>
   37 
   38 extern vm_offset_t      virtual_avail;
   39 
   40 /*
   41  * Allocate and map memory for devices that may need to be mapped 
   42  * outside the usual physical memory. If phys_addr is NULL then
   43  * steal the appropriate number of physical pages from the vm
   44  * system and map them.
   45  *
   46  * Note, this will onl
   47  */
   48 vm_offset_t
   49 io_map(phys_addr, size)
   50         vm_offset_t     phys_addr;
   51         vm_size_t       size;
   52 {
   53         vm_offset_t     start;
   54         int             i;
   55         unsigned int j;
   56         vm_page_t       m;
   57 
   58 
   59 #if DEBUG
   60         assert (kernel_map != VM_MAP_NULL);                     /* VM must be initialised */
   61 #endif
   62 
   63         if (phys_addr != 0) {                                           /* If they supplied a physical address, use it */
   64 
   65                 size = round_page(size + (phys_addr & PAGE_MASK));      /* Make sure we map all of it */
   66 
   67                 (void) kmem_alloc_pageable(kernel_map, &start, size);   /* Get some virtual addresses to use */
   68                 
   69                 (void)mapping_make(kernel_pmap, (addr64_t)start, (ppnum_t)(phys_addr >> 12), 
   70                         (mmFlgBlock | mmFlgUseAttr | mmFlgCInhib | mmFlgGuarded),       /* Map as I/O page */
   71                         (size >> 12), VM_PROT_READ|VM_PROT_WRITE);
   72 
   73                 return (start + (phys_addr & PAGE_MASK));       /* Pass back the physical address */
   74         
   75         } else {
   76         
   77                 (void) kmem_alloc_pageable(kernel_map, &start, size);   /* Get some virtual addresses */
   78 
   79                 mapping_prealloc(size);                                 /* Make sure there are enough free mappings */
   80 
   81                 for (i = 0; i < size ; i += PAGE_SIZE) {
   82                         m = VM_PAGE_NULL;
   83                         while ((m = vm_page_grab()) == VM_PAGE_NULL) {  /* Get a physical page */
   84                                 VM_PAGE_WAIT();                                 /* Wait if we didn't have one */
   85                         }
   86                         vm_page_gobble(m);
   87                         
   88                         (void)mapping_make(kernel_pmap, 
   89                                 (addr64_t)(start + i), m->phys_page, 
   90                                 (mmFlgBlock | mmFlgUseAttr | mmFlgCInhib | mmFlgGuarded),       /* Map as I/O page */
   91                                 1, VM_PROT_READ|VM_PROT_WRITE); 
   92                         
   93                 }
   94 
   95                 mapping_relpre();                                               /* Allow mapping release */
   96                 return start;
   97         }
   98 }
   99 
  100 
  101 /*
  102  * Allocate and map memory for devices before the VM system comes alive.
  103  */
  104 
  105 vm_offset_t io_map_spec(vm_offset_t phys_addr, vm_size_t size)
  106 {
  107         vm_offset_t     start;
  108 
  109         if(kernel_map != VM_MAP_NULL) {                         /* If VM system is up, redirect to normal routine */
  110                 
  111                 return io_map(phys_addr, size);                 /* Map the address */
  112         
  113         }
  114         
  115         size = round_page(size + (phys_addr - (phys_addr & -PAGE_SIZE)));       /* Extend the length to include it all */
  116         start = pmap_boot_map(size);                            /* Get me some virtual address */
  117 
  118         (void)mapping_make(kernel_pmap, (addr64_t)start, (ppnum_t)(phys_addr >> 12), 
  119                 (mmFlgBlock | mmFlgUseAttr | mmFlgCInhib | mmFlgGuarded),       /* Map as I/O page */
  120                 (size >> 12), VM_PROT_READ|VM_PROT_WRITE);
  121 
  122         return (start + (phys_addr & PAGE_MASK));
  123 }

Cache object: dbfef9031c165eb71b87bcabd6261b6b


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