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/pmap.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) 2001 The NetBSD Foundation, Inc.
    3  * All rights reserved.
    4  *
    5  * This code is derived from software contributed to The NetBSD Foundation
    6  * by Matt Thomas <matt@3am-software.com> of Allegro Networks, Inc.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  * 3. All advertising materials mentioning features or use of this software
   17  *    must display the following acknowledgement:
   18  *        This product includes software developed by the NetBSD
   19  *        Foundation, Inc. and its contributors.
   20  * 4. Neither the name of The NetBSD Foundation nor the names of its
   21  *    contributors may be used to endorse or promote products derived
   22  *    from this software without specific prior written permission.
   23  *
   24  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   25  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   26  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   27  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   28  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   29  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   30  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   31  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   32  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   33  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   34  * POSSIBILITY OF SUCH DAMAGE.
   35  */
   36 /*
   37  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
   38  * Copyright (C) 1995, 1996 TooLs GmbH.
   39  * All rights reserved.
   40  *
   41  * Redistribution and use in source and binary forms, with or without
   42  * modification, are permitted provided that the following conditions
   43  * are met:
   44  * 1. Redistributions of source code must retain the above copyright
   45  *    notice, this list of conditions and the following disclaimer.
   46  * 2. Redistributions in binary form must reproduce the above copyright
   47  *    notice, this list of conditions and the following disclaimer in the
   48  *    documentation and/or other materials provided with the distribution.
   49  * 3. All advertising materials mentioning features or use of this software
   50  *    must display the following acknowledgement:
   51  *      This product includes software developed by TooLs GmbH.
   52  * 4. The name of TooLs GmbH may not be used to endorse or promote products
   53  *    derived from this software without specific prior written permission.
   54  *
   55  * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
   56  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   57  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   58  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   59  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   60  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
   61  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
   62  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
   63  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
   64  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   65  *
   66  * $NetBSD: pmap.c,v 1.28 2000/03/26 20:42:36 kleink Exp $
   67  */
   68 /*
   69  * Copyright (C) 2001 Benno Rice.
   70  * All rights reserved.
   71  *
   72  * Redistribution and use in source and binary forms, with or without
   73  * modification, are permitted provided that the following conditions
   74  * are met:
   75  * 1. Redistributions of source code must retain the above copyright
   76  *    notice, this list of conditions and the following disclaimer.
   77  * 2. Redistributions in binary form must reproduce the above copyright
   78  *    notice, this list of conditions and the following disclaimer in the
   79  *    documentation and/or other materials provided with the distribution.
   80  *
   81  * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR
   82  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   83  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   84  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   85  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   86  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
   87  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
   88  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
   89  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
   90  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   91  */
   92 
   93 #include <sys/cdefs.h>
   94 __FBSDID("$FreeBSD: releng/5.2/sys/powerpc/powerpc/pmap.c 120722 2003-10-03 22:46:53Z alc $");
   95 
   96 /*
   97  * Manages physical address maps.
   98  *
   99  * In addition to hardware address maps, this module is called upon to
  100  * provide software-use-only maps which may or may not be stored in the
  101  * same form as hardware maps.  These pseudo-maps are used to store
  102  * intermediate results from copy operations to and from address spaces.
  103  *
  104  * Since the information managed by this module is also stored by the
  105  * logical address mapping module, this module may throw away valid virtual
  106  * to physical mappings at almost any time.  However, invalidations of
  107  * mappings must be done as requested.
  108  *
  109  * In order to cope with hardware architectures which make virtual to
  110  * physical map invalidates expensive, this module may delay invalidate
  111  * reduced protection operations until such time as they are actually
  112  * necessary.  This module is given full information as to which processors
  113  * are currently using which maps, and to when physical maps must be made
  114  * correct.
  115  */
  116 
  117 #include "opt_kstack_pages.h"
  118 
  119 #include <sys/param.h>
  120 #include <sys/kernel.h>
  121 #include <sys/ktr.h>
  122 #include <sys/lock.h>
  123 #include <sys/msgbuf.h>
  124 #include <sys/mutex.h>
  125 #include <sys/proc.h>
  126 #include <sys/sysctl.h>
  127 #include <sys/systm.h>
  128 #include <sys/vmmeter.h>
  129 
  130 #include <dev/ofw/openfirm.h>
  131 
  132 #include <vm/vm.h> 
  133 #include <vm/vm_param.h>
  134 #include <vm/vm_kern.h>
  135 #include <vm/vm_page.h>
  136 #include <vm/vm_map.h>
  137 #include <vm/vm_object.h>
  138 #include <vm/vm_extern.h>
  139 #include <vm/vm_pageout.h>
  140 #include <vm/vm_pager.h>
  141 #include <vm/uma.h>
  142 
  143 #include <machine/powerpc.h>
  144 #include <machine/bat.h>
  145 #include <machine/frame.h>
  146 #include <machine/md_var.h>
  147 #include <machine/psl.h>
  148 #include <machine/pte.h>
  149 #include <machine/sr.h>
  150 
  151 #define PMAP_DEBUG
  152 
  153 #define TODO    panic("%s: not implemented", __func__);
  154 
  155 #define PMAP_LOCK(pm)
  156 #define PMAP_UNLOCK(pm)
  157 
  158 #define TLBIE(va)       __asm __volatile("tlbie %0" :: "r"(va))
  159 #define TLBSYNC()       __asm __volatile("tlbsync");
  160 #define SYNC()          __asm __volatile("sync");
  161 #define EIEIO()         __asm __volatile("eieio");
  162 
  163 #define VSID_MAKE(sr, hash)     ((sr) | (((hash) & 0xfffff) << 4))
  164 #define VSID_TO_SR(vsid)        ((vsid) & 0xf)
  165 #define VSID_TO_HASH(vsid)      (((vsid) >> 4) & 0xfffff)
  166 
  167 #define PVO_PTEGIDX_MASK        0x0007          /* which PTEG slot */
  168 #define PVO_PTEGIDX_VALID       0x0008          /* slot is valid */
  169 #define PVO_WIRED               0x0010          /* PVO entry is wired */
  170 #define PVO_MANAGED             0x0020          /* PVO entry is managed */
  171 #define PVO_EXECUTABLE          0x0040          /* PVO entry is executable */
  172 #define PVO_BOOTSTRAP           0x0080          /* PVO entry allocated during
  173                                                    bootstrap */
  174 #define PVO_VADDR(pvo)          ((pvo)->pvo_vaddr & ~ADDR_POFF)
  175 #define PVO_ISEXECUTABLE(pvo)   ((pvo)->pvo_vaddr & PVO_EXECUTABLE)
  176 #define PVO_PTEGIDX_GET(pvo)    ((pvo)->pvo_vaddr & PVO_PTEGIDX_MASK)
  177 #define PVO_PTEGIDX_ISSET(pvo)  ((pvo)->pvo_vaddr & PVO_PTEGIDX_VALID)
  178 #define PVO_PTEGIDX_CLR(pvo)    \
  179         ((void)((pvo)->pvo_vaddr &= ~(PVO_PTEGIDX_VALID|PVO_PTEGIDX_MASK)))
  180 #define PVO_PTEGIDX_SET(pvo, i) \
  181         ((void)((pvo)->pvo_vaddr |= (i)|PVO_PTEGIDX_VALID))
  182 
  183 #define PMAP_PVO_CHECK(pvo)
  184 
  185 struct ofw_map {
  186         vm_offset_t     om_va;
  187         vm_size_t       om_len;
  188         vm_offset_t     om_pa;
  189         u_int           om_mode;
  190 };
  191 
  192 int     pmap_bootstrapped = 0;
  193 
  194 /*
  195  * Virtual and physical address of message buffer.
  196  */
  197 struct          msgbuf *msgbufp;
  198 vm_offset_t     msgbuf_phys;
  199 
  200 /*
  201  * Physical addresses of first and last available physical page.
  202  */
  203 vm_offset_t avail_start;
  204 vm_offset_t avail_end;
  205 
  206 int pmap_pagedaemon_waken;
  207 
  208 /*
  209  * Map of physical memory regions.
  210  */
  211 vm_offset_t     phys_avail[128];
  212 u_int           phys_avail_count;
  213 static struct   mem_region *regions;
  214 static struct   mem_region *pregions;
  215 int             regions_sz, pregions_sz;
  216 static struct   ofw_map *translations;
  217 
  218 /*
  219  * First and last available kernel virtual addresses.
  220  */
  221 vm_offset_t virtual_avail;
  222 vm_offset_t virtual_end;
  223 vm_offset_t kernel_vm_end;
  224 
  225 /*
  226  * Kernel pmap.
  227  */
  228 struct pmap kernel_pmap_store;
  229 extern struct pmap ofw_pmap;
  230 
  231 /*
  232  * PTEG data.
  233  */
  234 static struct   pteg *pmap_pteg_table;
  235 u_int           pmap_pteg_count;
  236 u_int           pmap_pteg_mask;
  237 
  238 /*
  239  * PVO data.
  240  */
  241 struct  pvo_head *pmap_pvo_table;               /* pvo entries by pteg index */
  242 struct  pvo_head pmap_pvo_kunmanaged =
  243     LIST_HEAD_INITIALIZER(pmap_pvo_kunmanaged); /* list of unmanaged pages */
  244 struct  pvo_head pmap_pvo_unmanaged =
  245     LIST_HEAD_INITIALIZER(pmap_pvo_unmanaged);  /* list of unmanaged pages */
  246 
  247 uma_zone_t      pmap_upvo_zone; /* zone for pvo entries for unmanaged pages */
  248 uma_zone_t      pmap_mpvo_zone; /* zone for pvo entries for managed pages */
  249 struct          vm_object pmap_upvo_zone_obj;
  250 struct          vm_object pmap_mpvo_zone_obj;
  251 
  252 #define BPVO_POOL_SIZE  32768
  253 static struct   pvo_entry *pmap_bpvo_pool;
  254 static int      pmap_bpvo_pool_index = 0;
  255 
  256 #define VSID_NBPW       (sizeof(u_int32_t) * 8)
  257 static u_int    pmap_vsid_bitmap[NPMAPS / VSID_NBPW];
  258 
  259 static boolean_t pmap_initialized = FALSE;
  260 
  261 /*
  262  * Statistics.
  263  */
  264 u_int   pmap_pte_valid = 0;
  265 u_int   pmap_pte_overflow = 0;
  266 u_int   pmap_pte_replacements = 0;
  267 u_int   pmap_pvo_entries = 0;
  268 u_int   pmap_pvo_enter_calls = 0;
  269 u_int   pmap_pvo_remove_calls = 0;
  270 u_int   pmap_pte_spills = 0;
  271 SYSCTL_INT(_machdep, OID_AUTO, pmap_pte_valid, CTLFLAG_RD, &pmap_pte_valid,
  272     0, "");
  273 SYSCTL_INT(_machdep, OID_AUTO, pmap_pte_overflow, CTLFLAG_RD,
  274     &pmap_pte_overflow, 0, "");
  275 SYSCTL_INT(_machdep, OID_AUTO, pmap_pte_replacements, CTLFLAG_RD,
  276     &pmap_pte_replacements, 0, "");
  277 SYSCTL_INT(_machdep, OID_AUTO, pmap_pvo_entries, CTLFLAG_RD, &pmap_pvo_entries,
  278     0, "");
  279 SYSCTL_INT(_machdep, OID_AUTO, pmap_pvo_enter_calls, CTLFLAG_RD,
  280     &pmap_pvo_enter_calls, 0, "");
  281 SYSCTL_INT(_machdep, OID_AUTO, pmap_pvo_remove_calls, CTLFLAG_RD,
  282     &pmap_pvo_remove_calls, 0, "");
  283 SYSCTL_INT(_machdep, OID_AUTO, pmap_pte_spills, CTLFLAG_RD,
  284     &pmap_pte_spills, 0, "");
  285 
  286 struct  pvo_entry *pmap_pvo_zeropage;
  287 
  288 vm_offset_t     pmap_rkva_start = VM_MIN_KERNEL_ADDRESS;
  289 u_int           pmap_rkva_count = 4;
  290 
  291 /*
  292  * Allocate physical memory for use in pmap_bootstrap.
  293  */
  294 static vm_offset_t      pmap_bootstrap_alloc(vm_size_t, u_int);
  295 
  296 /*
  297  * PTE calls.
  298  */
  299 static int              pmap_pte_insert(u_int, struct pte *);
  300 
  301 /*
  302  * PVO calls.
  303  */
  304 static int      pmap_pvo_enter(pmap_t, uma_zone_t, struct pvo_head *,
  305                     vm_offset_t, vm_offset_t, u_int, int);
  306 static void     pmap_pvo_remove(struct pvo_entry *, int);
  307 static struct   pvo_entry *pmap_pvo_find_va(pmap_t, vm_offset_t, int *);
  308 static struct   pte *pmap_pvo_to_pte(const struct pvo_entry *, int);
  309 
  310 /*
  311  * Utility routines.
  312  */
  313 static void *           pmap_pvo_allocf(uma_zone_t, int, u_int8_t *, int);
  314 static struct           pvo_entry *pmap_rkva_alloc(void);
  315 static void             pmap_pa_map(struct pvo_entry *, vm_offset_t,
  316                             struct pte *, int *);
  317 static void             pmap_pa_unmap(struct pvo_entry *, struct pte *, int *);
  318 static void             pmap_syncicache(vm_offset_t, vm_size_t);
  319 static boolean_t        pmap_query_bit(vm_page_t, int);
  320 static u_int            pmap_clear_bit(vm_page_t, int, int *);
  321 static void             tlbia(void);
  322 
  323 static __inline int
  324 va_to_sr(u_int *sr, vm_offset_t va)
  325 {
  326         return (sr[(uintptr_t)va >> ADDR_SR_SHFT]);
  327 }
  328 
  329 static __inline u_int
  330 va_to_pteg(u_int sr, vm_offset_t addr)
  331 {
  332         u_int hash;
  333 
  334         hash = (sr & SR_VSID_MASK) ^ (((u_int)addr & ADDR_PIDX) >>
  335             ADDR_PIDX_SHFT);
  336         return (hash & pmap_pteg_mask);
  337 }
  338 
  339 static __inline struct pvo_head *
  340 pa_to_pvoh(vm_offset_t pa, vm_page_t *pg_p)
  341 {
  342         struct  vm_page *pg;
  343 
  344         pg = PHYS_TO_VM_PAGE(pa);
  345 
  346         if (pg_p != NULL)
  347                 *pg_p = pg;
  348 
  349         if (pg == NULL)
  350                 return (&pmap_pvo_unmanaged);
  351 
  352         return (&pg->md.mdpg_pvoh);
  353 }
  354 
  355 static __inline struct pvo_head *
  356 vm_page_to_pvoh(vm_page_t m)
  357 {
  358 
  359         return (&m->md.mdpg_pvoh);
  360 }
  361 
  362 static __inline void
  363 pmap_attr_clear(vm_page_t m, int ptebit)
  364 {
  365 
  366         m->md.mdpg_attrs &= ~ptebit;
  367 }
  368 
  369 static __inline int
  370 pmap_attr_fetch(vm_page_t m)
  371 {
  372 
  373         return (m->md.mdpg_attrs);
  374 }
  375 
  376 static __inline void
  377 pmap_attr_save(vm_page_t m, int ptebit)
  378 {
  379 
  380         m->md.mdpg_attrs |= ptebit;
  381 }
  382 
  383 static __inline int
  384 pmap_pte_compare(const struct pte *pt, const struct pte *pvo_pt)
  385 {
  386         if (pt->pte_hi == pvo_pt->pte_hi)
  387                 return (1);
  388 
  389         return (0);
  390 }
  391 
  392 static __inline int
  393 pmap_pte_match(struct pte *pt, u_int sr, vm_offset_t va, int which)
  394 {
  395         return (pt->pte_hi & ~PTE_VALID) ==
  396             (((sr & SR_VSID_MASK) << PTE_VSID_SHFT) |
  397             ((va >> ADDR_API_SHFT) & PTE_API) | which);
  398 }
  399 
  400 static __inline void
  401 pmap_pte_create(struct pte *pt, u_int sr, vm_offset_t va, u_int pte_lo)
  402 {
  403         /*
  404          * Construct a PTE.  Default to IMB initially.  Valid bit only gets
  405          * set when the real pte is set in memory.
  406          *
  407          * Note: Don't set the valid bit for correct operation of tlb update.
  408          */
  409         pt->pte_hi = ((sr & SR_VSID_MASK) << PTE_VSID_SHFT) |
  410             (((va & ADDR_PIDX) >> ADDR_API_SHFT) & PTE_API);
  411         pt->pte_lo = pte_lo;
  412 }
  413 
  414 static __inline void
  415 pmap_pte_synch(struct pte *pt, struct pte *pvo_pt)
  416 {
  417 
  418         pvo_pt->pte_lo |= pt->pte_lo & (PTE_REF | PTE_CHG);
  419 }
  420 
  421 static __inline void
  422 pmap_pte_clear(struct pte *pt, vm_offset_t va, int ptebit)
  423 {
  424 
  425         /*
  426          * As shown in Section 7.6.3.2.3
  427          */
  428         pt->pte_lo &= ~ptebit;
  429         TLBIE(va);
  430         EIEIO();
  431         TLBSYNC();
  432         SYNC();
  433 }
  434 
  435 static __inline void
  436 pmap_pte_set(struct pte *pt, struct pte *pvo_pt)
  437 {
  438 
  439         pvo_pt->pte_hi |= PTE_VALID;
  440 
  441         /*
  442          * Update the PTE as defined in section 7.6.3.1.
  443          * Note that the REF/CHG bits are from pvo_pt and thus should havce
  444          * been saved so this routine can restore them (if desired).
  445          */
  446         pt->pte_lo = pvo_pt->pte_lo;
  447         EIEIO();
  448         pt->pte_hi = pvo_pt->pte_hi;
  449         SYNC();
  450         pmap_pte_valid++;
  451 }
  452 
  453 static __inline void
  454 pmap_pte_unset(struct pte *pt, struct pte *pvo_pt, vm_offset_t va)
  455 {
  456 
  457         pvo_pt->pte_hi &= ~PTE_VALID;
  458 
  459         /*
  460          * Force the reg & chg bits back into the PTEs.
  461          */
  462         SYNC();
  463 
  464         /*
  465          * Invalidate the pte.
  466          */
  467         pt->pte_hi &= ~PTE_VALID;
  468 
  469         SYNC();
  470         TLBIE(va);
  471         EIEIO();
  472         TLBSYNC();
  473         SYNC();
  474 
  475         /*
  476          * Save the reg & chg bits.
  477          */
  478         pmap_pte_synch(pt, pvo_pt);
  479         pmap_pte_valid--;
  480 }
  481 
  482 static __inline void
  483 pmap_pte_change(struct pte *pt, struct pte *pvo_pt, vm_offset_t va)
  484 {
  485 
  486         /*
  487          * Invalidate the PTE
  488          */
  489         pmap_pte_unset(pt, pvo_pt, va);
  490         pmap_pte_set(pt, pvo_pt);
  491 }
  492 
  493 /*
  494  * Quick sort callout for comparing memory regions.
  495  */
  496 static int      mr_cmp(const void *a, const void *b);
  497 static int      om_cmp(const void *a, const void *b);
  498 
  499 static int
  500 mr_cmp(const void *a, const void *b)
  501 {
  502         const struct    mem_region *regiona;
  503         const struct    mem_region *regionb;
  504 
  505         regiona = a;
  506         regionb = b;
  507         if (regiona->mr_start < regionb->mr_start)
  508                 return (-1);
  509         else if (regiona->mr_start > regionb->mr_start)
  510                 return (1);
  511         else
  512                 return (0);
  513 }
  514 
  515 static int
  516 om_cmp(const void *a, const void *b)
  517 {
  518         const struct    ofw_map *mapa;
  519         const struct    ofw_map *mapb;
  520 
  521         mapa = a;
  522         mapb = b;
  523         if (mapa->om_pa < mapb->om_pa)
  524                 return (-1);
  525         else if (mapa->om_pa > mapb->om_pa)
  526                 return (1);
  527         else
  528                 return (0);
  529 }
  530 
  531 void
  532 pmap_bootstrap(vm_offset_t kernelstart, vm_offset_t kernelend)
  533 {
  534         ihandle_t       mmui;
  535         phandle_t       chosen, mmu;
  536         int             sz;
  537         int             i, j;
  538         int             ofw_mappings;
  539         vm_size_t       size, physsz;
  540         vm_offset_t     pa, va, off;
  541         u_int           batl, batu;
  542 
  543         /*
  544          * Set up BAT0 to map the lowest 256 MB area
  545          */
  546         battable[0x0].batl = BATL(0x00000000, BAT_M, BAT_PP_RW);
  547         battable[0x0].batu = BATU(0x00000000, BAT_BL_256M, BAT_Vs);
  548 
  549         /*
  550          * Map PCI memory space.
  551          */
  552         battable[0x8].batl = BATL(0x80000000, BAT_I|BAT_G, BAT_PP_RW);
  553         battable[0x8].batu = BATU(0x80000000, BAT_BL_256M, BAT_Vs);
  554 
  555         battable[0x9].batl = BATL(0x90000000, BAT_I|BAT_G, BAT_PP_RW);
  556         battable[0x9].batu = BATU(0x90000000, BAT_BL_256M, BAT_Vs);
  557 
  558         battable[0xa].batl = BATL(0xa0000000, BAT_I|BAT_G, BAT_PP_RW);
  559         battable[0xa].batu = BATU(0xa0000000, BAT_BL_256M, BAT_Vs);
  560 
  561         battable[0xb].batl = BATL(0xb0000000, BAT_I|BAT_G, BAT_PP_RW);
  562         battable[0xb].batu = BATU(0xb0000000, BAT_BL_256M, BAT_Vs);
  563 
  564         /*
  565          * Map obio devices.
  566          */
  567         battable[0xf].batl = BATL(0xf0000000, BAT_I|BAT_G, BAT_PP_RW);
  568         battable[0xf].batu = BATU(0xf0000000, BAT_BL_256M, BAT_Vs);
  569 
  570         /*
  571          * Use an IBAT and a DBAT to map the bottom segment of memory
  572          * where we are.
  573          */
  574         batu = BATU(0x00000000, BAT_BL_256M, BAT_Vs);
  575         batl = BATL(0x00000000, BAT_M, BAT_PP_RW);
  576         __asm ("mtibatu 0,%0; mtibatl 0,%1; mtdbatu 0,%0; mtdbatl 0,%1"
  577             :: "r"(batu), "r"(batl));
  578 
  579 #if 0
  580         /* map frame buffer */
  581         batu = BATU(0x90000000, BAT_BL_256M, BAT_Vs);
  582         batl = BATL(0x90000000, BAT_I|BAT_G, BAT_PP_RW);
  583         __asm ("mtdbatu 1,%0; mtdbatl 1,%1"
  584             :: "r"(batu), "r"(batl));
  585 #endif
  586 
  587 #if 1
  588         /* map pci space */
  589         batu = BATU(0x80000000, BAT_BL_256M, BAT_Vs);
  590         batl = BATL(0x80000000, BAT_I|BAT_G, BAT_PP_RW);
  591         __asm ("mtdbatu 1,%0; mtdbatl 1,%1"
  592             :: "r"(batu), "r"(batl));
  593 #endif
  594 
  595         /*
  596          * Set the start and end of kva.
  597          */
  598         virtual_avail = VM_MIN_KERNEL_ADDRESS;
  599         virtual_end = VM_MAX_KERNEL_ADDRESS;
  600 
  601         mem_regions(&pregions, &pregions_sz, &regions, &regions_sz);
  602         CTR0(KTR_PMAP, "pmap_bootstrap: physical memory");
  603 
  604         qsort(pregions, pregions_sz, sizeof(*pregions), mr_cmp);
  605         for (i = 0; i < pregions_sz; i++) {
  606                 vm_offset_t pa;
  607                 vm_offset_t end;
  608 
  609                 CTR3(KTR_PMAP, "physregion: %#x - %#x (%#x)",
  610                         pregions[i].mr_start,
  611                         pregions[i].mr_start + pregions[i].mr_size,
  612                         pregions[i].mr_size);
  613                 /*
  614                  * Install entries into the BAT table to allow all
  615                  * of physmem to be convered by on-demand BAT entries.
  616                  * The loop will sometimes set the same battable element
  617                  * twice, but that's fine since they won't be used for
  618                  * a while yet.
  619                  */
  620                 pa = pregions[i].mr_start & 0xf0000000;
  621                 end = pregions[i].mr_start + pregions[i].mr_size;
  622                 do {
  623                         u_int n = pa >> ADDR_SR_SHFT;
  624                         
  625                         battable[n].batl = BATL(pa, BAT_M, BAT_PP_RW);
  626                         battable[n].batu = BATU(pa, BAT_BL_256M, BAT_Vs);
  627                         pa += SEGMENT_LENGTH;
  628                 } while (pa < end);
  629         }
  630 
  631         if (sizeof(phys_avail)/sizeof(phys_avail[0]) < regions_sz)
  632                 panic("pmap_bootstrap: phys_avail too small");
  633         qsort(regions, regions_sz, sizeof(*regions), mr_cmp);
  634         phys_avail_count = 0;
  635         physsz = 0;
  636         for (i = 0, j = 0; i < regions_sz; i++, j += 2) {
  637                 CTR3(KTR_PMAP, "region: %#x - %#x (%#x)", regions[i].mr_start,
  638                     regions[i].mr_start + regions[i].mr_size,
  639                     regions[i].mr_size);
  640                 phys_avail[j] = regions[i].mr_start;
  641                 phys_avail[j + 1] = regions[i].mr_start + regions[i].mr_size;
  642                 phys_avail_count++;
  643                 physsz += regions[i].mr_size;
  644         }
  645         physmem = btoc(physsz);
  646 
  647         /*
  648          * Allocate PTEG table.
  649          */
  650 #ifdef PTEGCOUNT
  651         pmap_pteg_count = PTEGCOUNT;
  652 #else
  653         pmap_pteg_count = 0x1000;
  654 
  655         while (pmap_pteg_count < physmem)
  656                 pmap_pteg_count <<= 1;
  657 
  658         pmap_pteg_count >>= 1;
  659 #endif /* PTEGCOUNT */
  660 
  661         size = pmap_pteg_count * sizeof(struct pteg);
  662         CTR2(KTR_PMAP, "pmap_bootstrap: %d PTEGs, %d bytes", pmap_pteg_count,
  663             size);
  664         pmap_pteg_table = (struct pteg *)pmap_bootstrap_alloc(size, size);
  665         CTR1(KTR_PMAP, "pmap_bootstrap: PTEG table at %p", pmap_pteg_table);
  666         bzero((void *)pmap_pteg_table, pmap_pteg_count * sizeof(struct pteg));
  667         pmap_pteg_mask = pmap_pteg_count - 1;
  668 
  669         /*
  670          * Allocate pv/overflow lists.
  671          */
  672         size = sizeof(struct pvo_head) * pmap_pteg_count;
  673         pmap_pvo_table = (struct pvo_head *)pmap_bootstrap_alloc(size,
  674             PAGE_SIZE);
  675         CTR1(KTR_PMAP, "pmap_bootstrap: PVO table at %p", pmap_pvo_table);
  676         for (i = 0; i < pmap_pteg_count; i++)
  677                 LIST_INIT(&pmap_pvo_table[i]);
  678 
  679         /*
  680          * Allocate the message buffer.
  681          */
  682         msgbuf_phys = pmap_bootstrap_alloc(MSGBUF_SIZE, 0);
  683 
  684         /*
  685          * Initialise the unmanaged pvo pool.
  686          */
  687         pmap_bpvo_pool = (struct pvo_entry *)pmap_bootstrap_alloc(
  688                 BPVO_POOL_SIZE*sizeof(struct pvo_entry), 0);
  689         pmap_bpvo_pool_index = 0;
  690 
  691         /*
  692          * Make sure kernel vsid is allocated as well as VSID 0.
  693          */
  694         pmap_vsid_bitmap[(KERNEL_VSIDBITS & (NPMAPS - 1)) / VSID_NBPW]
  695                 |= 1 << (KERNEL_VSIDBITS % VSID_NBPW);
  696         pmap_vsid_bitmap[0] |= 1;
  697 
  698         /*
  699          * Set up the OpenFirmware pmap and add it's mappings.
  700          */
  701         pmap_pinit(&ofw_pmap);
  702         ofw_pmap.pm_sr[KERNEL_SR] = KERNEL_SEGMENT;
  703         if ((chosen = OF_finddevice("/chosen")) == -1)
  704                 panic("pmap_bootstrap: can't find /chosen");
  705         OF_getprop(chosen, "mmu", &mmui, 4);
  706         if ((mmu = OF_instance_to_package(mmui)) == -1)
  707                 panic("pmap_bootstrap: can't get mmu package");
  708         if ((sz = OF_getproplen(mmu, "translations")) == -1)
  709                 panic("pmap_bootstrap: can't get ofw translation count");
  710         translations = NULL;
  711         for (i = 0; phys_avail[i + 2] != 0; i += 2) {
  712                 if (phys_avail[i + 1] >= sz)
  713                         translations = (struct ofw_map *)phys_avail[i];
  714         }
  715         if (translations == NULL)
  716                 panic("pmap_bootstrap: no space to copy translations");
  717         bzero(translations, sz);
  718         if (OF_getprop(mmu, "translations", translations, sz) == -1)
  719                 panic("pmap_bootstrap: can't get ofw translations");
  720         CTR0(KTR_PMAP, "pmap_bootstrap: translations");
  721         sz /= sizeof(*translations);
  722         qsort(translations, sz, sizeof (*translations), om_cmp);
  723         for (i = 0, ofw_mappings = 0; i < sz; i++) {
  724                 CTR3(KTR_PMAP, "translation: pa=%#x va=%#x len=%#x",
  725                     translations[i].om_pa, translations[i].om_va,
  726                     translations[i].om_len);
  727 
  728                 /*
  729                  * If the mapping is 1:1, let the RAM and device on-demand
  730                  * BAT tables take care of the translation.
  731                  */
  732                 if (translations[i].om_va == translations[i].om_pa)
  733                         continue;
  734 
  735                 /* Enter the pages */
  736                 for (off = 0; off < translations[i].om_len; off += PAGE_SIZE) {
  737                         struct  vm_page m;
  738 
  739                         m.phys_addr = translations[i].om_pa + off;
  740                         pmap_enter(&ofw_pmap, translations[i].om_va + off, &m,
  741                                    VM_PROT_ALL, 1);
  742                         ofw_mappings++;
  743                 }
  744         }
  745 #ifdef SMP
  746         TLBSYNC();
  747 #endif
  748 
  749         /*
  750          * Initialize the kernel pmap (which is statically allocated).
  751          */
  752         for (i = 0; i < 16; i++) {
  753                 kernel_pmap->pm_sr[i] = EMPTY_SEGMENT;
  754         }
  755         kernel_pmap->pm_sr[KERNEL_SR] = KERNEL_SEGMENT;
  756         kernel_pmap->pm_active = ~0;
  757 
  758         /*
  759          * Allocate a kernel stack with a guard page for thread0 and map it
  760          * into the kernel page map.
  761          */
  762         pa = pmap_bootstrap_alloc(KSTACK_PAGES * PAGE_SIZE, 0);
  763         kstack0_phys = pa;
  764         kstack0 = virtual_avail + (KSTACK_GUARD_PAGES * PAGE_SIZE);
  765         CTR2(KTR_PMAP, "pmap_bootstrap: kstack0 at %#x (%#x)", kstack0_phys,
  766             kstack0);
  767         virtual_avail += (KSTACK_PAGES + KSTACK_GUARD_PAGES) * PAGE_SIZE;
  768         for (i = 0; i < KSTACK_PAGES; i++) {
  769                 pa = kstack0_phys + i * PAGE_SIZE;
  770                 va = kstack0 + i * PAGE_SIZE;
  771                 pmap_kenter(va, pa);
  772                 TLBIE(va);
  773         }
  774 
  775         /*
  776          * Calculate the first and last available physical addresses.
  777          */
  778         avail_start = phys_avail[0];
  779         for (i = 0; phys_avail[i + 2] != 0; i += 2)
  780                 ;
  781         avail_end = phys_avail[i + 1];
  782         Maxmem = powerpc_btop(avail_end);
  783 
  784         /*
  785          * Allocate virtual address space for the message buffer.
  786          */
  787         msgbufp = (struct msgbuf *)virtual_avail;
  788         virtual_avail += round_page(MSGBUF_SIZE);
  789 
  790         /*
  791          * Initialize hardware.
  792          */
  793         for (i = 0; i < 16; i++) {
  794                 mtsrin(i << ADDR_SR_SHFT, EMPTY_SEGMENT);
  795         }
  796         __asm __volatile ("mtsr %0,%1"
  797             :: "n"(KERNEL_SR), "r"(KERNEL_SEGMENT));
  798         __asm __volatile ("sync; mtsdr1 %0; isync"
  799             :: "r"((u_int)pmap_pteg_table | (pmap_pteg_mask >> 10)));
  800         tlbia();
  801 
  802         pmap_bootstrapped++;
  803 }
  804 
  805 /*
  806  * Activate a user pmap.  The pmap must be activated before it's address
  807  * space can be accessed in any way.
  808  */
  809 void
  810 pmap_activate(struct thread *td)
  811 {
  812         pmap_t  pm, pmr;
  813 
  814         /*
  815          * Load all the data we need up front to encourage the compiler to
  816          * not issue any loads while we have interrupts disabled below.
  817          */
  818         pm = &td->td_proc->p_vmspace->vm_pmap;
  819 
  820         if ((pmr = (pmap_t)pmap_kextract((vm_offset_t)pm)) == NULL)
  821                 pmr = pm;
  822 
  823         pm->pm_active |= PCPU_GET(cpumask);
  824         PCPU_SET(curpmap, pmr);
  825 }
  826 
  827 void
  828 pmap_deactivate(struct thread *td)
  829 {
  830         pmap_t  pm;
  831 
  832         pm = &td->td_proc->p_vmspace->vm_pmap;
  833         pm->pm_active &= ~(PCPU_GET(cpumask));
  834         PCPU_SET(curpmap, NULL);
  835 }
  836 
  837 vm_offset_t
  838 pmap_addr_hint(vm_object_t object, vm_offset_t va, vm_size_t size)
  839 {
  840 
  841         return (va);
  842 }
  843 
  844 void
  845 pmap_change_wiring(pmap_t pm, vm_offset_t va, boolean_t wired)
  846 {
  847         struct  pvo_entry *pvo;
  848 
  849         pvo = pmap_pvo_find_va(pm, va & ~ADDR_POFF, NULL);
  850 
  851         if (pvo != NULL) {
  852                 if (wired) {
  853                         if ((pvo->pvo_vaddr & PVO_WIRED) == 0)
  854                                 pm->pm_stats.wired_count++;
  855                         pvo->pvo_vaddr |= PVO_WIRED;
  856                 } else {
  857                         if ((pvo->pvo_vaddr & PVO_WIRED) != 0)
  858                                 pm->pm_stats.wired_count--;
  859                         pvo->pvo_vaddr &= ~PVO_WIRED;
  860                 }
  861         }
  862 }
  863 
  864 void
  865 pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr,
  866           vm_size_t len, vm_offset_t src_addr)
  867 {
  868 
  869         /*
  870          * This is not needed as it's mainly an optimisation.
  871          * It may want to be implemented later though.
  872          */
  873 }
  874 
  875 void
  876 pmap_copy_page(vm_page_t msrc, vm_page_t mdst)
  877 {
  878         vm_offset_t     dst;
  879         vm_offset_t     src;
  880 
  881         dst = VM_PAGE_TO_PHYS(mdst);
  882         src = VM_PAGE_TO_PHYS(msrc);
  883 
  884         kcopy((void *)src, (void *)dst, PAGE_SIZE);
  885 }
  886 
  887 /*
  888  * Zero a page of physical memory by temporarily mapping it into the tlb.
  889  */
  890 void
  891 pmap_zero_page(vm_page_t m)
  892 {
  893         vm_offset_t pa = VM_PAGE_TO_PHYS(m);
  894         caddr_t va;
  895 
  896         if (pa < SEGMENT_LENGTH) {
  897                 va = (caddr_t) pa;
  898         } else if (pmap_initialized) {
  899                 if (pmap_pvo_zeropage == NULL)
  900                         pmap_pvo_zeropage = pmap_rkva_alloc();
  901                 pmap_pa_map(pmap_pvo_zeropage, pa, NULL, NULL);
  902                 va = (caddr_t)PVO_VADDR(pmap_pvo_zeropage);
  903         } else {
  904                 panic("pmap_zero_page: can't zero pa %#x", pa);
  905         }
  906 
  907         bzero(va, PAGE_SIZE);
  908 
  909         if (pa >= SEGMENT_LENGTH)
  910                 pmap_pa_unmap(pmap_pvo_zeropage, NULL, NULL);
  911 }
  912 
  913 void
  914 pmap_zero_page_area(vm_page_t m, int off, int size)
  915 {
  916         vm_offset_t pa = VM_PAGE_TO_PHYS(m);
  917         caddr_t va;
  918 
  919         if (pa < SEGMENT_LENGTH) {
  920                 va = (caddr_t) pa;
  921         } else if (pmap_initialized) {
  922                 if (pmap_pvo_zeropage == NULL)
  923                         pmap_pvo_zeropage = pmap_rkva_alloc();
  924                 pmap_pa_map(pmap_pvo_zeropage, pa, NULL, NULL);
  925                 va = (caddr_t)PVO_VADDR(pmap_pvo_zeropage);
  926         } else {
  927                 panic("pmap_zero_page: can't zero pa %#x", pa);
  928         }
  929 
  930         bzero(va + off, size);
  931 
  932         if (pa >= SEGMENT_LENGTH)
  933                 pmap_pa_unmap(pmap_pvo_zeropage, NULL, NULL);
  934 }
  935 
  936 void
  937 pmap_zero_page_idle(vm_page_t m)
  938 {
  939 
  940         /* XXX this is called outside of Giant, is pmap_zero_page safe? */
  941         /* XXX maybe have a dedicated mapping for this to avoid the problem? */
  942         mtx_lock(&Giant);
  943         pmap_zero_page(m);
  944         mtx_unlock(&Giant);
  945 }
  946 
  947 /*
  948  * Map the given physical page at the specified virtual address in the
  949  * target pmap with the protection requested.  If specified the page
  950  * will be wired down.
  951  */
  952 void
  953 pmap_enter(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot,
  954            boolean_t wired)
  955 {
  956         struct          pvo_head *pvo_head;
  957         uma_zone_t      zone;
  958         vm_page_t       pg;
  959         u_int           pte_lo, pvo_flags, was_exec, i;
  960         int             error;
  961 
  962         if (!pmap_initialized) {
  963                 pvo_head = &pmap_pvo_kunmanaged;
  964                 zone = pmap_upvo_zone;
  965                 pvo_flags = 0;
  966                 pg = NULL;
  967                 was_exec = PTE_EXEC;
  968         } else {
  969                 pvo_head = vm_page_to_pvoh(m);
  970                 pg = m;
  971                 zone = pmap_mpvo_zone;
  972                 pvo_flags = PVO_MANAGED;
  973                 was_exec = 0;
  974         }
  975 
  976         /*
  977          * If this is a managed page, and it's the first reference to the page,
  978          * clear the execness of the page.  Otherwise fetch the execness.
  979          */
  980         if (pg != NULL) {
  981                 if (LIST_EMPTY(pvo_head)) {
  982                         pmap_attr_clear(pg, PTE_EXEC);
  983                 } else {
  984                         was_exec = pmap_attr_fetch(pg) & PTE_EXEC;
  985                 }
  986         }
  987 
  988 
  989         /*
  990          * Assume the page is cache inhibited and access is guarded unless
  991          * it's in our available memory array.
  992          */
  993         pte_lo = PTE_I | PTE_G;
  994         for (i = 0; i < pregions_sz; i++) {
  995                 if ((VM_PAGE_TO_PHYS(m) >= pregions[i].mr_start) &&
  996                     (VM_PAGE_TO_PHYS(m) < 
  997                         (pregions[i].mr_start + pregions[i].mr_size))) {
  998                         pte_lo &= ~(PTE_I | PTE_G);
  999                         break;
 1000                 }
 1001         }
 1002 
 1003         if (prot & VM_PROT_WRITE)
 1004                 pte_lo |= PTE_BW;
 1005         else
 1006                 pte_lo |= PTE_BR;
 1007 
 1008         pvo_flags |= (prot & VM_PROT_EXECUTE);
 1009 
 1010         if (wired)
 1011                 pvo_flags |= PVO_WIRED;
 1012 
 1013         error = pmap_pvo_enter(pmap, zone, pvo_head, va, VM_PAGE_TO_PHYS(m),
 1014             pte_lo, pvo_flags);
 1015 
 1016         /*
 1017          * Flush the real page from the instruction cache if this page is
 1018          * mapped executable and cacheable and was not previously mapped (or
 1019          * was not mapped executable).
 1020          */
 1021         if (error == 0 && (pvo_flags & PVO_EXECUTABLE) &&
 1022             (pte_lo & PTE_I) == 0 && was_exec == 0) {
 1023                 /*
 1024                  * Flush the real memory from the cache.
 1025                  */
 1026                 pmap_syncicache(VM_PAGE_TO_PHYS(m), PAGE_SIZE);
 1027                 if (pg != NULL)
 1028                         pmap_attr_save(pg, PTE_EXEC);
 1029         }
 1030 
 1031         /* XXX syncicache always until problems are sorted */
 1032         pmap_syncicache(VM_PAGE_TO_PHYS(m), PAGE_SIZE);
 1033 }
 1034 
 1035 vm_page_t
 1036 pmap_enter_quick(pmap_t pm, vm_offset_t va, vm_page_t m, vm_page_t mpte)
 1037 {
 1038 
 1039         pmap_enter(pm, va, m, VM_PROT_READ | VM_PROT_EXECUTE, FALSE);
 1040         return (NULL);
 1041 }
 1042 
 1043 vm_offset_t
 1044 pmap_extract(pmap_t pm, vm_offset_t va)
 1045 {
 1046         struct  pvo_entry *pvo;
 1047 
 1048         pvo = pmap_pvo_find_va(pm, va & ~ADDR_POFF, NULL);
 1049 
 1050         if (pvo != NULL) {
 1051                 return ((pvo->pvo_pte.pte_lo & PTE_RPGN) | (va & ADDR_POFF));
 1052         }
 1053 
 1054         return (0);
 1055 }
 1056 
 1057 /*
 1058  * Atomically extract and hold the physical page with the given
 1059  * pmap and virtual address pair if that mapping permits the given
 1060  * protection.
 1061  */
 1062 vm_page_t
 1063 pmap_extract_and_hold(pmap_t pmap, vm_offset_t va, vm_prot_t prot)
 1064 {
 1065         vm_paddr_t pa;
 1066         vm_page_t m;
 1067         
 1068         m = NULL;
 1069         mtx_lock(&Giant);
 1070         if ((pa = pmap_extract(pmap, va)) != 0) {
 1071                 m = PHYS_TO_VM_PAGE(pa);
 1072                 vm_page_lock_queues();
 1073                 vm_page_hold(m);
 1074                 vm_page_unlock_queues();
 1075         }
 1076         mtx_unlock(&Giant);
 1077         return (m);
 1078 }
 1079 
 1080 /*
 1081  * Grow the number of kernel page table entries.  Unneeded.
 1082  */
 1083 void
 1084 pmap_growkernel(vm_offset_t addr)
 1085 {
 1086 }
 1087 
 1088 void
 1089 pmap_init(vm_offset_t phys_start, vm_offset_t phys_end)
 1090 {
 1091 
 1092         CTR0(KTR_PMAP, "pmap_init");
 1093 
 1094         pmap_upvo_zone = uma_zcreate("UPVO entry", sizeof (struct pvo_entry),
 1095             NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_VM | UMA_ZONE_NOFREE);
 1096         uma_zone_set_allocf(pmap_upvo_zone, pmap_pvo_allocf);
 1097         pmap_mpvo_zone = uma_zcreate("MPVO entry", sizeof(struct pvo_entry),
 1098             NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_VM | UMA_ZONE_NOFREE);
 1099         uma_zone_set_allocf(pmap_mpvo_zone, pmap_pvo_allocf);
 1100         pmap_initialized = TRUE;
 1101 }
 1102 
 1103 void
 1104 pmap_init2(void)
 1105 {
 1106 
 1107         CTR0(KTR_PMAP, "pmap_init2");
 1108 }
 1109 
 1110 boolean_t
 1111 pmap_is_modified(vm_page_t m)
 1112 {
 1113 
 1114         if ((m->flags & (PG_FICTITIOUS |PG_UNMANAGED)) != 0)
 1115                 return (FALSE);
 1116 
 1117         return (pmap_query_bit(m, PTE_CHG));
 1118 }
 1119 
 1120 /*
 1121  *      pmap_is_prefaultable:
 1122  *
 1123  *      Return whether or not the specified virtual address is elgible
 1124  *      for prefault.
 1125  */
 1126 boolean_t
 1127 pmap_is_prefaultable(pmap_t pmap, vm_offset_t addr)
 1128 {
 1129 
 1130         return (FALSE);
 1131 }
 1132 
 1133 void
 1134 pmap_clear_reference(vm_page_t m)
 1135 {
 1136 
 1137         if ((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) != 0)
 1138                 return;
 1139         pmap_clear_bit(m, PTE_REF, NULL);
 1140 }
 1141 
 1142 void
 1143 pmap_clear_modify(vm_page_t m)
 1144 {
 1145 
 1146         if ((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) != 0)
 1147                 return;
 1148         pmap_clear_bit(m, PTE_CHG, NULL);
 1149 }
 1150 
 1151 /*
 1152  *      pmap_ts_referenced:
 1153  *
 1154  *      Return a count of reference bits for a page, clearing those bits.
 1155  *      It is not necessary for every reference bit to be cleared, but it
 1156  *      is necessary that 0 only be returned when there are truly no
 1157  *      reference bits set.
 1158  *
 1159  *      XXX: The exact number of bits to check and clear is a matter that
 1160  *      should be tested and standardized at some point in the future for
 1161  *      optimal aging of shared pages.
 1162  */
 1163 int
 1164 pmap_ts_referenced(vm_page_t m)
 1165 {
 1166         int count;
 1167 
 1168         if ((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) != 0)
 1169                 return (0);
 1170 
 1171         count = pmap_clear_bit(m, PTE_REF, NULL);
 1172 
 1173         return (count);
 1174 }
 1175 
 1176 /*
 1177  * Map a wired page into kernel virtual address space.
 1178  */
 1179 void
 1180 pmap_kenter(vm_offset_t va, vm_offset_t pa)
 1181 {
 1182         u_int           pte_lo;
 1183         int             error;  
 1184         int             i;
 1185 
 1186 #if 0
 1187         if (va < VM_MIN_KERNEL_ADDRESS)
 1188                 panic("pmap_kenter: attempt to enter non-kernel address %#x",
 1189                     va);
 1190 #endif
 1191 
 1192         pte_lo = PTE_I | PTE_G;
 1193         for (i = 0; i < pregions_sz; i++) {
 1194                 if ((pa >= pregions[i].mr_start) &&
 1195                     (pa < (pregions[i].mr_start + pregions[i].mr_size))) {
 1196                         pte_lo &= ~(PTE_I | PTE_G);
 1197                         break;
 1198                 }
 1199         }       
 1200 
 1201         error = pmap_pvo_enter(kernel_pmap, pmap_upvo_zone,
 1202             &pmap_pvo_kunmanaged, va, pa, pte_lo, PVO_WIRED);
 1203 
 1204         if (error != 0 && error != ENOENT)
 1205                 panic("pmap_kenter: failed to enter va %#x pa %#x: %d", va,
 1206                     pa, error);
 1207 
 1208         /*
 1209          * Flush the real memory from the instruction cache.
 1210          */
 1211         if ((pte_lo & (PTE_I | PTE_G)) == 0) {
 1212                 pmap_syncicache(pa, PAGE_SIZE);
 1213         }
 1214 }
 1215 
 1216 /*
 1217  * Extract the physical page address associated with the given kernel virtual
 1218  * address.
 1219  */
 1220 vm_offset_t
 1221 pmap_kextract(vm_offset_t va)
 1222 {
 1223         struct          pvo_entry *pvo;
 1224 
 1225         pvo = pmap_pvo_find_va(kernel_pmap, va & ~ADDR_POFF, NULL);
 1226         if (pvo == NULL) {
 1227                 return (0);
 1228         }
 1229 
 1230         return ((pvo->pvo_pte.pte_lo & PTE_RPGN) | (va & ADDR_POFF));
 1231 }
 1232 
 1233 /*
 1234  * Remove a wired page from kernel virtual address space.
 1235  */
 1236 void
 1237 pmap_kremove(vm_offset_t va)
 1238 {
 1239 
 1240         pmap_remove(kernel_pmap, va, va + PAGE_SIZE);
 1241 }
 1242 
 1243 /*
 1244  * Map a range of physical addresses into kernel virtual address space.
 1245  *
 1246  * The value passed in *virt is a suggested virtual address for the mapping.
 1247  * Architectures which can support a direct-mapped physical to virtual region
 1248  * can return the appropriate address within that region, leaving '*virt'
 1249  * unchanged.  We cannot and therefore do not; *virt is updated with the
 1250  * first usable address after the mapped region.
 1251  */
 1252 vm_offset_t
 1253 pmap_map(vm_offset_t *virt, vm_offset_t pa_start, vm_offset_t pa_end, int prot)
 1254 {
 1255         vm_offset_t     sva, va;
 1256 
 1257         sva = *virt;
 1258         va = sva;
 1259         for (; pa_start < pa_end; pa_start += PAGE_SIZE, va += PAGE_SIZE)
 1260                 pmap_kenter(va, pa_start);
 1261         *virt = va;
 1262         return (sva);
 1263 }
 1264 
 1265 int
 1266 pmap_mincore(pmap_t pmap, vm_offset_t addr)
 1267 {
 1268         TODO;
 1269         return (0);
 1270 }
 1271 
 1272 void
 1273 pmap_object_init_pt(pmap_t pm, vm_offset_t addr, vm_object_t object,
 1274                     vm_pindex_t pindex, vm_size_t size)
 1275 {
 1276 
 1277         VM_OBJECT_LOCK_ASSERT(object, MA_OWNED);
 1278         KASSERT(object->type == OBJT_DEVICE,
 1279             ("pmap_object_init_pt: non-device object"));
 1280         KASSERT(pm == &curproc->p_vmspace->vm_pmap || pm == kernel_pmap,
 1281             ("pmap_object_init_pt: non current pmap"));
 1282 }
 1283 
 1284 /*
 1285  * Lower the permission for all mappings to a given page.
 1286  */
 1287 void
 1288 pmap_page_protect(vm_page_t m, vm_prot_t prot)
 1289 {
 1290         struct  pvo_head *pvo_head;
 1291         struct  pvo_entry *pvo, *next_pvo;
 1292         struct  pte *pt;
 1293 
 1294         /*
 1295          * Since the routine only downgrades protection, if the
 1296          * maximal protection is desired, there isn't any change
 1297          * to be made.
 1298          */
 1299         if ((prot & (VM_PROT_READ|VM_PROT_WRITE)) ==
 1300             (VM_PROT_READ|VM_PROT_WRITE))
 1301                 return;
 1302 
 1303         pvo_head = vm_page_to_pvoh(m);
 1304         for (pvo = LIST_FIRST(pvo_head); pvo != NULL; pvo = next_pvo) {
 1305                 next_pvo = LIST_NEXT(pvo, pvo_vlink);
 1306                 PMAP_PVO_CHECK(pvo);    /* sanity check */
 1307 
 1308                 /*
 1309                  * Downgrading to no mapping at all, we just remove the entry.
 1310                  */
 1311                 if ((prot & VM_PROT_READ) == 0) {
 1312                         pmap_pvo_remove(pvo, -1);
 1313                         continue;
 1314                 }
 1315 
 1316                 /*
 1317                  * If EXEC permission is being revoked, just clear the flag
 1318                  * in the PVO.
 1319                  */
 1320                 if ((prot & VM_PROT_EXECUTE) == 0)
 1321                         pvo->pvo_vaddr &= ~PVO_EXECUTABLE;
 1322 
 1323                 /*
 1324                  * If this entry is already RO, don't diddle with the page
 1325                  * table.
 1326                  */
 1327                 if ((pvo->pvo_pte.pte_lo & PTE_PP) == PTE_BR) {
 1328                         PMAP_PVO_CHECK(pvo);
 1329                         continue;
 1330                 }
 1331 
 1332                 /*
 1333                  * Grab the PTE before we diddle the bits so pvo_to_pte can
 1334                  * verify the pte contents are as expected.
 1335                  */
 1336                 pt = pmap_pvo_to_pte(pvo, -1);
 1337                 pvo->pvo_pte.pte_lo &= ~PTE_PP;
 1338                 pvo->pvo_pte.pte_lo |= PTE_BR;
 1339                 if (pt != NULL)
 1340                         pmap_pte_change(pt, &pvo->pvo_pte, pvo->pvo_vaddr);
 1341                 PMAP_PVO_CHECK(pvo);    /* sanity check */
 1342         }
 1343 }
 1344 
 1345 /*
 1346  * Returns true if the pmap's pv is one of the first
 1347  * 16 pvs linked to from this page.  This count may
 1348  * be changed upwards or downwards in the future; it
 1349  * is only necessary that true be returned for a small
 1350  * subset of pmaps for proper page aging.
 1351  */
 1352 boolean_t
 1353 pmap_page_exists_quick(pmap_t pmap, vm_page_t m)
 1354 {
 1355         int loops;
 1356         struct pvo_entry *pvo;
 1357 
 1358         if (!pmap_initialized || (m->flags & PG_FICTITIOUS))
 1359                 return FALSE;
 1360 
 1361         loops = 0;
 1362         LIST_FOREACH(pvo, vm_page_to_pvoh(m), pvo_vlink) {
 1363                 if (pvo->pvo_pmap == pmap)
 1364                         return (TRUE);
 1365                 if (++loops >= 16)
 1366                         break;
 1367         }
 1368 
 1369         return (FALSE);
 1370 }
 1371 
 1372 static u_int    pmap_vsidcontext;
 1373 
 1374 void
 1375 pmap_pinit(pmap_t pmap)
 1376 {
 1377         int     i, mask;
 1378         u_int   entropy;
 1379 
 1380         entropy = 0;
 1381         __asm __volatile("mftb %0" : "=r"(entropy));
 1382 
 1383         /*
 1384          * Allocate some segment registers for this pmap.
 1385          */
 1386         for (i = 0; i < NPMAPS; i += VSID_NBPW) {
 1387                 u_int   hash, n;
 1388 
 1389                 /*
 1390                  * Create a new value by mutiplying by a prime and adding in
 1391                  * entropy from the timebase register.  This is to make the
 1392                  * VSID more random so that the PT hash function collides
 1393                  * less often.  (Note that the prime casues gcc to do shifts
 1394                  * instead of a multiply.)
 1395                  */
 1396                 pmap_vsidcontext = (pmap_vsidcontext * 0x1105) + entropy;
 1397                 hash = pmap_vsidcontext & (NPMAPS - 1);
 1398                 if (hash == 0)          /* 0 is special, avoid it */
 1399                         continue;
 1400                 n = hash >> 5;
 1401                 mask = 1 << (hash & (VSID_NBPW - 1));
 1402                 hash = (pmap_vsidcontext & 0xfffff);
 1403                 if (pmap_vsid_bitmap[n] & mask) {       /* collision? */
 1404                         /* anything free in this bucket? */
 1405                         if (pmap_vsid_bitmap[n] == 0xffffffff) {
 1406                                 entropy = (pmap_vsidcontext >> 20);
 1407                                 continue;
 1408                         }
 1409                         i = ffs(~pmap_vsid_bitmap[i]) - 1;
 1410                         mask = 1 << i;
 1411                         hash &= 0xfffff & ~(VSID_NBPW - 1);
 1412                         hash |= i;
 1413                 }
 1414                 pmap_vsid_bitmap[n] |= mask;
 1415                 for (i = 0; i < 16; i++)
 1416                         pmap->pm_sr[i] = VSID_MAKE(i, hash);
 1417                 return;
 1418         }
 1419 
 1420         panic("pmap_pinit: out of segments");
 1421 }
 1422 
 1423 /*
 1424  * Initialize the pmap associated with process 0.
 1425  */
 1426 void
 1427 pmap_pinit0(pmap_t pm)
 1428 {
 1429 
 1430         pmap_pinit(pm);
 1431         bzero(&pm->pm_stats, sizeof(pm->pm_stats));
 1432 }
 1433 
 1434 void
 1435 pmap_pinit2(pmap_t pmap)
 1436 {
 1437         /* XXX: Remove this stub when no longer called */
 1438 }
 1439 
 1440 /*
 1441  * Set the physical protection on the specified range of this map as requested.
 1442  */
 1443 void
 1444 pmap_protect(pmap_t pm, vm_offset_t sva, vm_offset_t eva, vm_prot_t prot)
 1445 {
 1446         struct  pvo_entry *pvo;
 1447         struct  pte *pt;
 1448         int     pteidx;
 1449 
 1450         CTR4(KTR_PMAP, "pmap_protect: pm=%p sva=%#x eva=%#x prot=%#x", pm, sva,
 1451             eva, prot);
 1452 
 1453 
 1454         KASSERT(pm == &curproc->p_vmspace->vm_pmap || pm == kernel_pmap,
 1455             ("pmap_protect: non current pmap"));
 1456 
 1457         if ((prot & VM_PROT_READ) == VM_PROT_NONE) {
 1458                 pmap_remove(pm, sva, eva);
 1459                 return;
 1460         }
 1461 
 1462         for (; sva < eva; sva += PAGE_SIZE) {
 1463                 pvo = pmap_pvo_find_va(pm, sva, &pteidx);
 1464                 if (pvo == NULL)
 1465                         continue;
 1466 
 1467                 if ((prot & VM_PROT_EXECUTE) == 0)
 1468                         pvo->pvo_vaddr &= ~PVO_EXECUTABLE;
 1469 
 1470                 /*
 1471                  * Grab the PTE pointer before we diddle with the cached PTE
 1472                  * copy.
 1473                  */
 1474                 pt = pmap_pvo_to_pte(pvo, pteidx);
 1475                 /*
 1476                  * Change the protection of the page.
 1477                  */
 1478                 pvo->pvo_pte.pte_lo &= ~PTE_PP;
 1479                 pvo->pvo_pte.pte_lo |= PTE_BR;
 1480 
 1481                 /*
 1482                  * If the PVO is in the page table, update that pte as well.
 1483                  */
 1484                 if (pt != NULL)
 1485                         pmap_pte_change(pt, &pvo->pvo_pte, pvo->pvo_vaddr);
 1486         }
 1487 }
 1488 
 1489 /*
 1490  * Map a list of wired pages into kernel virtual address space.  This is
 1491  * intended for temporary mappings which do not need page modification or
 1492  * references recorded.  Existing mappings in the region are overwritten.
 1493  */
 1494 void
 1495 pmap_qenter(vm_offset_t sva, vm_page_t *m, int count)
 1496 {
 1497         vm_offset_t va;
 1498 
 1499         va = sva;
 1500         while (count-- > 0) {
 1501                 pmap_kenter(va, VM_PAGE_TO_PHYS(*m));
 1502                 va += PAGE_SIZE;
 1503                 m++;
 1504         }
 1505 }
 1506 
 1507 /*
 1508  * Remove page mappings from kernel virtual address space.  Intended for
 1509  * temporary mappings entered by pmap_qenter.
 1510  */
 1511 void
 1512 pmap_qremove(vm_offset_t sva, int count)
 1513 {
 1514         vm_offset_t va;
 1515 
 1516         va = sva;
 1517         while (count-- > 0) {
 1518                 pmap_kremove(va);
 1519                 va += PAGE_SIZE;
 1520         }
 1521 }
 1522 
 1523 void
 1524 pmap_release(pmap_t pmap)
 1525 {
 1526         int idx, mask;
 1527         
 1528         /*
 1529          * Free segment register's VSID
 1530          */
 1531         if (pmap->pm_sr[0] == 0)
 1532                 panic("pmap_release");
 1533 
 1534         idx = VSID_TO_HASH(pmap->pm_sr[0]) & (NPMAPS-1);
 1535         mask = 1 << (idx % VSID_NBPW);
 1536         idx /= VSID_NBPW;
 1537         pmap_vsid_bitmap[idx] &= ~mask;
 1538 }
 1539 
 1540 /*
 1541  * Remove the given range of addresses from the specified map.
 1542  */
 1543 void
 1544 pmap_remove(pmap_t pm, vm_offset_t sva, vm_offset_t eva)
 1545 {
 1546         struct  pvo_entry *pvo;
 1547         int     pteidx;
 1548 
 1549         for (; sva < eva; sva += PAGE_SIZE) {
 1550                 pvo = pmap_pvo_find_va(pm, sva, &pteidx);
 1551                 if (pvo != NULL) {
 1552                         pmap_pvo_remove(pvo, pteidx);
 1553                 }
 1554         }
 1555 }
 1556 
 1557 /*
 1558  * Remove physical page from all pmaps in which it resides. pmap_pvo_remove()
 1559  * will reflect changes in pte's back to the vm_page.
 1560  */
 1561 void
 1562 pmap_remove_all(vm_page_t m)
 1563 {
 1564         struct  pvo_head *pvo_head;
 1565         struct  pvo_entry *pvo, *next_pvo;
 1566 
 1567         mtx_assert(&vm_page_queue_mtx, MA_OWNED);
 1568 
 1569         pvo_head = vm_page_to_pvoh(m);
 1570         for (pvo = LIST_FIRST(pvo_head); pvo != NULL; pvo = next_pvo) {
 1571                 next_pvo = LIST_NEXT(pvo, pvo_vlink);
 1572                 
 1573                 PMAP_PVO_CHECK(pvo);    /* sanity check */
 1574                 pmap_pvo_remove(pvo, -1);
 1575         }
 1576         vm_page_flag_clear(m, PG_WRITEABLE);
 1577 }
 1578 
 1579 /*
 1580  * Remove all pages from specified address space, this aids process exit
 1581  * speeds.  This is much faster than pmap_remove in the case of running down
 1582  * an entire address space.  Only works for the current pmap.
 1583  */
 1584 void
 1585 pmap_remove_pages(pmap_t pm, vm_offset_t sva, vm_offset_t eva)
 1586 {
 1587 
 1588         KASSERT(pm == &curproc->p_vmspace->vm_pmap || pm == kernel_pmap,
 1589             ("pmap_remove_pages: non current pmap"));
 1590         pmap_remove(pm, sva, eva);
 1591 }
 1592 
 1593 /*
 1594  * Allocate a physical page of memory directly from the phys_avail map.
 1595  * Can only be called from pmap_bootstrap before avail start and end are
 1596  * calculated.
 1597  */
 1598 static vm_offset_t
 1599 pmap_bootstrap_alloc(vm_size_t size, u_int align)
 1600 {
 1601         vm_offset_t     s, e;
 1602         int             i, j;
 1603 
 1604         size = round_page(size);
 1605         for (i = 0; phys_avail[i + 1] != 0; i += 2) {
 1606                 if (align != 0)
 1607                         s = (phys_avail[i] + align - 1) & ~(align - 1);
 1608                 else
 1609                         s = phys_avail[i];
 1610                 e = s + size;
 1611 
 1612                 if (s < phys_avail[i] || e > phys_avail[i + 1])
 1613                         continue;
 1614 
 1615                 if (s == phys_avail[i]) {
 1616                         phys_avail[i] += size;
 1617                 } else if (e == phys_avail[i + 1]) {
 1618                         phys_avail[i + 1] -= size;
 1619                 } else {
 1620                         for (j = phys_avail_count * 2; j > i; j -= 2) {
 1621                                 phys_avail[j] = phys_avail[j - 2];
 1622                                 phys_avail[j + 1] = phys_avail[j - 1];
 1623                         }
 1624 
 1625                         phys_avail[i + 3] = phys_avail[i + 1];
 1626                         phys_avail[i + 1] = s;
 1627                         phys_avail[i + 2] = e;
 1628                         phys_avail_count++;
 1629                 }
 1630 
 1631                 return (s);
 1632         }
 1633         panic("pmap_bootstrap_alloc: could not allocate memory");
 1634 }
 1635 
 1636 /*
 1637  * Return an unmapped pvo for a kernel virtual address.
 1638  * Used by pmap functions that operate on physical pages.
 1639  */
 1640 static struct pvo_entry *
 1641 pmap_rkva_alloc(void)
 1642 {
 1643         struct          pvo_entry *pvo;
 1644         struct          pte *pt;
 1645         vm_offset_t     kva;
 1646         int             pteidx;
 1647 
 1648         if (pmap_rkva_count == 0)
 1649                 panic("pmap_rkva_alloc: no more reserved KVAs");
 1650 
 1651         kva = pmap_rkva_start + (PAGE_SIZE * --pmap_rkva_count);
 1652         pmap_kenter(kva, 0);
 1653 
 1654         pvo = pmap_pvo_find_va(kernel_pmap, kva, &pteidx);
 1655 
 1656         if (pvo == NULL)
 1657                 panic("pmap_kva_alloc: pmap_pvo_find_va failed");
 1658 
 1659         pt = pmap_pvo_to_pte(pvo, pteidx);
 1660 
 1661         if (pt == NULL)
 1662                 panic("pmap_kva_alloc: pmap_pvo_to_pte failed");
 1663 
 1664         pmap_pte_unset(pt, &pvo->pvo_pte, pvo->pvo_vaddr);
 1665         PVO_PTEGIDX_CLR(pvo);
 1666 
 1667         pmap_pte_overflow++;
 1668 
 1669         return (pvo);
 1670 }
 1671 
 1672 static void
 1673 pmap_pa_map(struct pvo_entry *pvo, vm_offset_t pa, struct pte *saved_pt,
 1674     int *depth_p)
 1675 {
 1676         struct  pte *pt;
 1677 
 1678         /*
 1679          * If this pvo already has a valid pte, we need to save it so it can
 1680          * be restored later.  We then just reload the new PTE over the old
 1681          * slot.
 1682          */
 1683         if (saved_pt != NULL) {
 1684                 pt = pmap_pvo_to_pte(pvo, -1);
 1685 
 1686                 if (pt != NULL) {
 1687                         pmap_pte_unset(pt, &pvo->pvo_pte, pvo->pvo_vaddr);
 1688                         PVO_PTEGIDX_CLR(pvo);
 1689                         pmap_pte_overflow++;
 1690                 }
 1691 
 1692                 *saved_pt = pvo->pvo_pte;
 1693 
 1694                 pvo->pvo_pte.pte_lo &= ~PTE_RPGN;
 1695         }
 1696 
 1697         pvo->pvo_pte.pte_lo |= pa;
 1698 
 1699         if (!pmap_pte_spill(pvo->pvo_vaddr))
 1700                 panic("pmap_pa_map: could not spill pvo %p", pvo);
 1701 
 1702         if (depth_p != NULL)
 1703                 (*depth_p)++;
 1704 }
 1705 
 1706 static void
 1707 pmap_pa_unmap(struct pvo_entry *pvo, struct pte *saved_pt, int *depth_p)
 1708 {
 1709         struct  pte *pt;
 1710 
 1711         pt = pmap_pvo_to_pte(pvo, -1);
 1712 
 1713         if (pt != NULL) {
 1714                 pmap_pte_unset(pt, &pvo->pvo_pte, pvo->pvo_vaddr);
 1715                 PVO_PTEGIDX_CLR(pvo);
 1716                 pmap_pte_overflow++;
 1717         }
 1718 
 1719         pvo->pvo_pte.pte_lo &= ~PTE_RPGN;
 1720 
 1721         /*
 1722          * If there is a saved PTE and it's valid, restore it and return.
 1723          */
 1724         if (saved_pt != NULL && (saved_pt->pte_lo & PTE_RPGN) != 0) {
 1725                 if (depth_p != NULL && --(*depth_p) == 0)
 1726                         panic("pmap_pa_unmap: restoring but depth == 0");
 1727 
 1728                 pvo->pvo_pte = *saved_pt;
 1729 
 1730                 if (!pmap_pte_spill(pvo->pvo_vaddr))
 1731                         panic("pmap_pa_unmap: could not spill pvo %p", pvo);
 1732         }
 1733 }
 1734 
 1735 static void
 1736 pmap_syncicache(vm_offset_t pa, vm_size_t len)
 1737 {
 1738         __syncicache((void *)pa, len);
 1739 }
 1740 
 1741 static void
 1742 tlbia(void)
 1743 {
 1744         caddr_t i;
 1745 
 1746         SYNC();
 1747         for (i = 0; i < (caddr_t)0x00040000; i += 0x00001000) {
 1748                 TLBIE(i);
 1749                 EIEIO();
 1750         }
 1751         TLBSYNC();
 1752         SYNC();
 1753 }
 1754 
 1755 static int
 1756 pmap_pvo_enter(pmap_t pm, uma_zone_t zone, struct pvo_head *pvo_head,
 1757     vm_offset_t va, vm_offset_t pa, u_int pte_lo, int flags)
 1758 {
 1759         struct  pvo_entry *pvo;
 1760         u_int   sr;
 1761         int     first;
 1762         u_int   ptegidx;
 1763         int     i;
 1764         int     bootstrap;
 1765 
 1766         pmap_pvo_enter_calls++;
 1767         first = 0;
 1768         
 1769         bootstrap = 0;
 1770 
 1771         /*
 1772          * Compute the PTE Group index.
 1773          */
 1774         va &= ~ADDR_POFF;
 1775         sr = va_to_sr(pm->pm_sr, va);
 1776         ptegidx = va_to_pteg(sr, va);
 1777 
 1778         /*
 1779          * Remove any existing mapping for this page.  Reuse the pvo entry if
 1780          * there is a mapping.
 1781          */
 1782         LIST_FOREACH(pvo, &pmap_pvo_table[ptegidx], pvo_olink) {
 1783                 if (pvo->pvo_pmap == pm && PVO_VADDR(pvo) == va) {
 1784                         if ((pvo->pvo_pte.pte_lo & PTE_RPGN) == pa &&
 1785                             (pvo->pvo_pte.pte_lo & PTE_PP) ==
 1786                             (pte_lo & PTE_PP)) {
 1787                                 return (0);
 1788                         }
 1789                         pmap_pvo_remove(pvo, -1);
 1790                         break;
 1791                 }
 1792         }
 1793 
 1794         /*
 1795          * If we aren't overwriting a mapping, try to allocate.
 1796          */
 1797         if (pmap_initialized) {
 1798                 pvo = uma_zalloc(zone, M_NOWAIT);
 1799         } else {
 1800                 if (pmap_bpvo_pool_index >= BPVO_POOL_SIZE) {
 1801                         panic("pmap_enter: bpvo pool exhausted, %d, %d, %d",
 1802                               pmap_bpvo_pool_index, BPVO_POOL_SIZE, 
 1803                               BPVO_POOL_SIZE * sizeof(struct pvo_entry));
 1804                 }
 1805                 pvo = &pmap_bpvo_pool[pmap_bpvo_pool_index];
 1806                 pmap_bpvo_pool_index++;
 1807                 bootstrap = 1;
 1808         }
 1809 
 1810         if (pvo == NULL) {
 1811                 return (ENOMEM);
 1812         }
 1813 
 1814         pmap_pvo_entries++;
 1815         pvo->pvo_vaddr = va;
 1816         pvo->pvo_pmap = pm;
 1817         LIST_INSERT_HEAD(&pmap_pvo_table[ptegidx], pvo, pvo_olink);
 1818         pvo->pvo_vaddr &= ~ADDR_POFF;
 1819         if (flags & VM_PROT_EXECUTE)
 1820                 pvo->pvo_vaddr |= PVO_EXECUTABLE;
 1821         if (flags & PVO_WIRED)
 1822                 pvo->pvo_vaddr |= PVO_WIRED;
 1823         if (pvo_head != &pmap_pvo_kunmanaged)
 1824                 pvo->pvo_vaddr |= PVO_MANAGED;
 1825         if (bootstrap)
 1826                 pvo->pvo_vaddr |= PVO_BOOTSTRAP;
 1827         pmap_pte_create(&pvo->pvo_pte, sr, va, pa | pte_lo);
 1828 
 1829         /*
 1830          * Remember if the list was empty and therefore will be the first
 1831          * item.
 1832          */
 1833         if (LIST_FIRST(pvo_head) == NULL)
 1834                 first = 1;
 1835 
 1836         LIST_INSERT_HEAD(pvo_head, pvo, pvo_vlink);
 1837         if (pvo->pvo_pte.pte_lo & PVO_WIRED)
 1838                 pvo->pvo_pmap->pm_stats.wired_count++;
 1839         pvo->pvo_pmap->pm_stats.resident_count++;
 1840 
 1841         /*
 1842          * We hope this succeeds but it isn't required.
 1843          */
 1844         i = pmap_pte_insert(ptegidx, &pvo->pvo_pte);
 1845         if (i >= 0) {
 1846                 PVO_PTEGIDX_SET(pvo, i);
 1847         } else {
 1848                 panic("pmap_pvo_enter: overflow");
 1849                 pmap_pte_overflow++;
 1850         }
 1851 
 1852         return (first ? ENOENT : 0);
 1853 }
 1854 
 1855 static void
 1856 pmap_pvo_remove(struct pvo_entry *pvo, int pteidx)
 1857 {
 1858         struct  pte *pt;
 1859 
 1860         /*
 1861          * If there is an active pte entry, we need to deactivate it (and
 1862          * save the ref & cfg bits).
 1863          */
 1864         pt = pmap_pvo_to_pte(pvo, pteidx);
 1865         if (pt != NULL) {
 1866                 pmap_pte_unset(pt, &pvo->pvo_pte, pvo->pvo_vaddr);
 1867                 PVO_PTEGIDX_CLR(pvo);
 1868         } else {
 1869                 pmap_pte_overflow--;
 1870         }       
 1871 
 1872         /*
 1873          * Update our statistics.
 1874          */
 1875         pvo->pvo_pmap->pm_stats.resident_count--;
 1876         if (pvo->pvo_pte.pte_lo & PVO_WIRED)
 1877                 pvo->pvo_pmap->pm_stats.wired_count--;
 1878 
 1879         /*
 1880          * Save the REF/CHG bits into their cache if the page is managed.
 1881          */
 1882         if (pvo->pvo_vaddr & PVO_MANAGED) {
 1883                 struct  vm_page *pg;
 1884 
 1885                 pg = PHYS_TO_VM_PAGE(pvo->pvo_pte.pte_lo & PTE_RPGN);
 1886                 if (pg != NULL) {
 1887                         pmap_attr_save(pg, pvo->pvo_pte.pte_lo &
 1888                             (PTE_REF | PTE_CHG));
 1889                 }
 1890         }
 1891 
 1892         /*
 1893          * Remove this PVO from the PV list.
 1894          */
 1895         LIST_REMOVE(pvo, pvo_vlink);
 1896 
 1897         /*
 1898          * Remove this from the overflow list and return it to the pool
 1899          * if we aren't going to reuse it.
 1900          */
 1901         LIST_REMOVE(pvo, pvo_olink);
 1902         if (!(pvo->pvo_vaddr & PVO_BOOTSTRAP))
 1903                 uma_zfree(pvo->pvo_vaddr & PVO_MANAGED ? pmap_mpvo_zone :
 1904                     pmap_upvo_zone, pvo);
 1905         pmap_pvo_entries--;
 1906         pmap_pvo_remove_calls++;
 1907 }
 1908 
 1909 static __inline int
 1910 pmap_pvo_pte_index(const struct pvo_entry *pvo, int ptegidx)
 1911 {
 1912         int     pteidx;
 1913 
 1914         /*
 1915          * We can find the actual pte entry without searching by grabbing
 1916          * the PTEG index from 3 unused bits in pte_lo[11:9] and by
 1917          * noticing the HID bit.
 1918          */
 1919         pteidx = ptegidx * 8 + PVO_PTEGIDX_GET(pvo);
 1920         if (pvo->pvo_pte.pte_hi & PTE_HID)
 1921                 pteidx ^= pmap_pteg_mask * 8;
 1922 
 1923         return (pteidx);
 1924 }
 1925 
 1926 static struct pvo_entry *
 1927 pmap_pvo_find_va(pmap_t pm, vm_offset_t va, int *pteidx_p)
 1928 {
 1929         struct  pvo_entry *pvo;
 1930         int     ptegidx;
 1931         u_int   sr;
 1932 
 1933         va &= ~ADDR_POFF;
 1934         sr = va_to_sr(pm->pm_sr, va);
 1935         ptegidx = va_to_pteg(sr, va);
 1936 
 1937         LIST_FOREACH(pvo, &pmap_pvo_table[ptegidx], pvo_olink) {
 1938                 if (pvo->pvo_pmap == pm && PVO_VADDR(pvo) == va) {
 1939                         if (pteidx_p)
 1940                                 *pteidx_p = pmap_pvo_pte_index(pvo, ptegidx);
 1941                         return (pvo);
 1942                 }
 1943         }
 1944 
 1945         return (NULL);
 1946 }
 1947 
 1948 static struct pte *
 1949 pmap_pvo_to_pte(const struct pvo_entry *pvo, int pteidx)
 1950 {
 1951         struct  pte *pt;
 1952 
 1953         /*
 1954          * If we haven't been supplied the ptegidx, calculate it.
 1955          */
 1956         if (pteidx == -1) {
 1957                 int     ptegidx;
 1958                 u_int   sr;
 1959 
 1960                 sr = va_to_sr(pvo->pvo_pmap->pm_sr, pvo->pvo_vaddr);
 1961                 ptegidx = va_to_pteg(sr, pvo->pvo_vaddr);
 1962                 pteidx = pmap_pvo_pte_index(pvo, ptegidx);
 1963         }
 1964 
 1965         pt = &pmap_pteg_table[pteidx >> 3].pt[pteidx & 7];
 1966 
 1967         if ((pvo->pvo_pte.pte_hi & PTE_VALID) && !PVO_PTEGIDX_ISSET(pvo)) {
 1968                 panic("pmap_pvo_to_pte: pvo %p has valid pte in pvo but no "
 1969                     "valid pte index", pvo);
 1970         }
 1971 
 1972         if ((pvo->pvo_pte.pte_hi & PTE_VALID) == 0 && PVO_PTEGIDX_ISSET(pvo)) {
 1973                 panic("pmap_pvo_to_pte: pvo %p has valid pte index in pvo "
 1974                     "pvo but no valid pte", pvo);
 1975         }
 1976 
 1977         if ((pt->pte_hi ^ (pvo->pvo_pte.pte_hi & ~PTE_VALID)) == PTE_VALID) {
 1978                 if ((pvo->pvo_pte.pte_hi & PTE_VALID) == 0) {
 1979                         panic("pmap_pvo_to_pte: pvo %p has valid pte in "
 1980                             "pmap_pteg_table %p but invalid in pvo", pvo, pt);
 1981                 }
 1982 
 1983                 if (((pt->pte_lo ^ pvo->pvo_pte.pte_lo) & ~(PTE_CHG|PTE_REF))
 1984                     != 0) {
 1985                         panic("pmap_pvo_to_pte: pvo %p pte does not match "
 1986                             "pte %p in pmap_pteg_table", pvo, pt);
 1987                 }
 1988 
 1989                 return (pt);
 1990         }
 1991 
 1992         if (pvo->pvo_pte.pte_hi & PTE_VALID) {
 1993                 panic("pmap_pvo_to_pte: pvo %p has invalid pte %p in "
 1994                     "pmap_pteg_table but valid in pvo", pvo, pt);
 1995         }
 1996 
 1997         return (NULL);
 1998 }
 1999 
 2000 static void *
 2001 pmap_pvo_allocf(uma_zone_t zone, int bytes, u_int8_t *flags, int wait)
 2002 {
 2003         static vm_pindex_t color;
 2004         vm_page_t       m;
 2005 
 2006         if (bytes != PAGE_SIZE)
 2007                 panic("pmap_pvo_allocf: benno was shortsighted.  hit him.");
 2008 
 2009         *flags = UMA_SLAB_PRIV;
 2010         /*
 2011          * The color is only a hint.  Thus, a data race in the read-
 2012          * modify-write operation below isn't a catastrophe.
 2013          */
 2014         m = vm_page_alloc(NULL, color++, VM_ALLOC_NOOBJ | VM_ALLOC_SYSTEM);
 2015         if (m == NULL)
 2016                 return (NULL);
 2017         return ((void *)VM_PAGE_TO_PHYS(m));
 2018 }
 2019 
 2020 /*
 2021  * XXX: THIS STUFF SHOULD BE IN pte.c?
 2022  */
 2023 int
 2024 pmap_pte_spill(vm_offset_t addr)
 2025 {
 2026         struct  pvo_entry *source_pvo, *victim_pvo;
 2027         struct  pvo_entry *pvo;
 2028         int     ptegidx, i, j;
 2029         u_int   sr;
 2030         struct  pteg *pteg;
 2031         struct  pte *pt;
 2032 
 2033         pmap_pte_spills++;
 2034 
 2035         sr = mfsrin(addr);
 2036         ptegidx = va_to_pteg(sr, addr);
 2037 
 2038         /*
 2039          * Have to substitute some entry.  Use the primary hash for this.
 2040          * Use low bits of timebase as random generator.
 2041          */
 2042         pteg = &pmap_pteg_table[ptegidx];
 2043         __asm __volatile("mftb %0" : "=r"(i));
 2044         i &= 7;
 2045         pt = &pteg->pt[i];
 2046 
 2047         source_pvo = NULL;
 2048         victim_pvo = NULL;
 2049         LIST_FOREACH(pvo, &pmap_pvo_table[ptegidx], pvo_olink) {
 2050                 /*
 2051                  * We need to find a pvo entry for this address.
 2052                  */
 2053                 PMAP_PVO_CHECK(pvo);
 2054                 if (source_pvo == NULL &&
 2055                     pmap_pte_match(&pvo->pvo_pte, sr, addr,
 2056                     pvo->pvo_pte.pte_hi & PTE_HID)) {
 2057                         /*
 2058                          * Now found an entry to be spilled into the pteg.
 2059                          * The PTE is now valid, so we know it's active.
 2060                          */
 2061                         j = pmap_pte_insert(ptegidx, &pvo->pvo_pte);
 2062 
 2063                         if (j >= 0) {
 2064                                 PVO_PTEGIDX_SET(pvo, j);
 2065                                 pmap_pte_overflow--;
 2066                                 PMAP_PVO_CHECK(pvo);
 2067                                 return (1);
 2068                         }
 2069 
 2070                         source_pvo = pvo;
 2071 
 2072                         if (victim_pvo != NULL)
 2073                                 break;
 2074                 }
 2075 
 2076                 /*
 2077                  * We also need the pvo entry of the victim we are replacing
 2078                  * so save the R & C bits of the PTE.
 2079                  */
 2080                 if ((pt->pte_hi & PTE_HID) == 0 && victim_pvo == NULL &&
 2081                     pmap_pte_compare(pt, &pvo->pvo_pte)) {
 2082                         victim_pvo = pvo;
 2083                         if (source_pvo != NULL)
 2084                                 break;
 2085                 }
 2086         }
 2087 
 2088         if (source_pvo == NULL)
 2089                 return (0);
 2090 
 2091         if (victim_pvo == NULL) {
 2092                 if ((pt->pte_hi & PTE_HID) == 0)
 2093                         panic("pmap_pte_spill: victim p-pte (%p) has no pvo"
 2094                             "entry", pt);
 2095 
 2096                 /*
 2097                  * If this is a secondary PTE, we need to search it's primary
 2098                  * pvo bucket for the matching PVO.
 2099                  */
 2100                 LIST_FOREACH(pvo, &pmap_pvo_table[ptegidx ^ pmap_pteg_mask],
 2101                     pvo_olink) {
 2102                         PMAP_PVO_CHECK(pvo);
 2103                         /*
 2104                          * We also need the pvo entry of the victim we are
 2105                          * replacing so save the R & C bits of the PTE.
 2106                          */
 2107                         if (pmap_pte_compare(pt, &pvo->pvo_pte)) {
 2108                                 victim_pvo = pvo;
 2109                                 break;
 2110                         }
 2111                 }
 2112 
 2113                 if (victim_pvo == NULL)
 2114                         panic("pmap_pte_spill: victim s-pte (%p) has no pvo"
 2115                             "entry", pt);
 2116         }
 2117 
 2118         /*
 2119          * We are invalidating the TLB entry for the EA we are replacing even
 2120          * though it's valid.  If we don't, we lose any ref/chg bit changes
 2121          * contained in the TLB entry.
 2122          */
 2123         source_pvo->pvo_pte.pte_hi &= ~PTE_HID;
 2124 
 2125         pmap_pte_unset(pt, &victim_pvo->pvo_pte, victim_pvo->pvo_vaddr);
 2126         pmap_pte_set(pt, &source_pvo->pvo_pte);
 2127 
 2128         PVO_PTEGIDX_CLR(victim_pvo);
 2129         PVO_PTEGIDX_SET(source_pvo, i);
 2130         pmap_pte_replacements++;
 2131 
 2132         PMAP_PVO_CHECK(victim_pvo);
 2133         PMAP_PVO_CHECK(source_pvo);
 2134 
 2135         return (1);
 2136 }
 2137 
 2138 static int
 2139 pmap_pte_insert(u_int ptegidx, struct pte *pvo_pt)
 2140 {
 2141         struct  pte *pt;
 2142         int     i;
 2143 
 2144         /*
 2145          * First try primary hash.
 2146          */
 2147         for (pt = pmap_pteg_table[ptegidx].pt, i = 0; i < 8; i++, pt++) {
 2148                 if ((pt->pte_hi & PTE_VALID) == 0) {
 2149                         pvo_pt->pte_hi &= ~PTE_HID;
 2150                         pmap_pte_set(pt, pvo_pt);
 2151                         return (i);
 2152                 }
 2153         }
 2154 
 2155         /*
 2156          * Now try secondary hash.
 2157          */
 2158         ptegidx ^= pmap_pteg_mask;
 2159         ptegidx++;
 2160         for (pt = pmap_pteg_table[ptegidx].pt, i = 0; i < 8; i++, pt++) {
 2161                 if ((pt->pte_hi & PTE_VALID) == 0) {
 2162                         pvo_pt->pte_hi |= PTE_HID;
 2163                         pmap_pte_set(pt, pvo_pt);
 2164                         return (i);
 2165                 }
 2166         }
 2167 
 2168         panic("pmap_pte_insert: overflow");
 2169         return (-1);
 2170 }
 2171 
 2172 static boolean_t
 2173 pmap_query_bit(vm_page_t m, int ptebit)
 2174 {
 2175         struct  pvo_entry *pvo;
 2176         struct  pte *pt;
 2177 
 2178         if (pmap_attr_fetch(m) & ptebit)
 2179                 return (TRUE);
 2180 
 2181         LIST_FOREACH(pvo, vm_page_to_pvoh(m), pvo_vlink) {
 2182                 PMAP_PVO_CHECK(pvo);    /* sanity check */
 2183 
 2184                 /*
 2185                  * See if we saved the bit off.  If so, cache it and return
 2186                  * success.
 2187                  */
 2188                 if (pvo->pvo_pte.pte_lo & ptebit) {
 2189                         pmap_attr_save(m, ptebit);
 2190                         PMAP_PVO_CHECK(pvo);    /* sanity check */
 2191                         return (TRUE);
 2192                 }
 2193         }
 2194 
 2195         /*
 2196          * No luck, now go through the hard part of looking at the PTEs
 2197          * themselves.  Sync so that any pending REF/CHG bits are flushed to
 2198          * the PTEs.
 2199          */
 2200         SYNC();
 2201         LIST_FOREACH(pvo, vm_page_to_pvoh(m), pvo_vlink) {
 2202                 PMAP_PVO_CHECK(pvo);    /* sanity check */
 2203 
 2204                 /*
 2205                  * See if this pvo has a valid PTE.  if so, fetch the
 2206                  * REF/CHG bits from the valid PTE.  If the appropriate
 2207                  * ptebit is set, cache it and return success.
 2208                  */
 2209                 pt = pmap_pvo_to_pte(pvo, -1);
 2210                 if (pt != NULL) {
 2211                         pmap_pte_synch(pt, &pvo->pvo_pte);
 2212                         if (pvo->pvo_pte.pte_lo & ptebit) {
 2213                                 pmap_attr_save(m, ptebit);
 2214                                 PMAP_PVO_CHECK(pvo);    /* sanity check */
 2215                                 return (TRUE);
 2216                         }
 2217                 }
 2218         }
 2219 
 2220         return (TRUE);
 2221 }
 2222 
 2223 static u_int
 2224 pmap_clear_bit(vm_page_t m, int ptebit, int *origbit)
 2225 {
 2226         u_int   count;
 2227         struct  pvo_entry *pvo;
 2228         struct  pte *pt;
 2229         int     rv;
 2230 
 2231         /*
 2232          * Clear the cached value.
 2233          */
 2234         rv = pmap_attr_fetch(m);
 2235         pmap_attr_clear(m, ptebit);
 2236 
 2237         /*
 2238          * Sync so that any pending REF/CHG bits are flushed to the PTEs (so
 2239          * we can reset the right ones).  note that since the pvo entries and
 2240          * list heads are accessed via BAT0 and are never placed in the page
 2241          * table, we don't have to worry about further accesses setting the
 2242          * REF/CHG bits.
 2243          */
 2244         SYNC();
 2245 
 2246         /*
 2247          * For each pvo entry, clear the pvo's ptebit.  If this pvo has a
 2248          * valid pte clear the ptebit from the valid pte.
 2249          */
 2250         count = 0;
 2251         LIST_FOREACH(pvo, vm_page_to_pvoh(m), pvo_vlink) {
 2252                 PMAP_PVO_CHECK(pvo);    /* sanity check */
 2253                 pt = pmap_pvo_to_pte(pvo, -1);
 2254                 if (pt != NULL) {
 2255                         pmap_pte_synch(pt, &pvo->pvo_pte);
 2256                         if (pvo->pvo_pte.pte_lo & ptebit) {
 2257                                 count++;
 2258                                 pmap_pte_clear(pt, PVO_VADDR(pvo), ptebit);
 2259                         }
 2260                 }
 2261                 rv |= pvo->pvo_pte.pte_lo;
 2262                 pvo->pvo_pte.pte_lo &= ~ptebit;
 2263                 PMAP_PVO_CHECK(pvo);    /* sanity check */
 2264         }
 2265 
 2266         if (origbit != NULL) {
 2267                 *origbit = rv;
 2268         }
 2269 
 2270         return (count);
 2271 }
 2272 
 2273 /*
 2274  * Return true if the physical range is encompassed by the battable[idx]
 2275  */
 2276 static int
 2277 pmap_bat_mapped(int idx, vm_offset_t pa, vm_size_t size)
 2278 {
 2279         u_int prot;
 2280         u_int32_t start;
 2281         u_int32_t end;
 2282         u_int32_t bat_ble;
 2283 
 2284         /*
 2285          * Return immediately if not a valid mapping
 2286          */
 2287         if (!battable[idx].batu & BAT_Vs)
 2288                 return (EINVAL);
 2289 
 2290         /*
 2291          * The BAT entry must be cache-inhibited, guarded, and r/w
 2292          * so it can function as an i/o page
 2293          */
 2294         prot = battable[idx].batl & (BAT_I|BAT_G|BAT_PP_RW);
 2295         if (prot != (BAT_I|BAT_G|BAT_PP_RW))
 2296                 return (EPERM); 
 2297 
 2298         /*
 2299          * The address should be within the BAT range. Assume that the
 2300          * start address in the BAT has the correct alignment (thus
 2301          * not requiring masking)
 2302          */
 2303         start = battable[idx].batl & BAT_PBS;
 2304         bat_ble = (battable[idx].batu & ~(BAT_EBS)) | 0x03;
 2305         end = start | (bat_ble << 15) | 0x7fff;
 2306 
 2307         if ((pa < start) || ((pa + size) > end))
 2308                 return (ERANGE);
 2309 
 2310         return (0);
 2311 }
 2312 
 2313 
 2314 /*
 2315  * Map a set of physical memory pages into the kernel virtual
 2316  * address space. Return a pointer to where it is mapped. This
 2317  * routine is intended to be used for mapping device memory,
 2318  * NOT real memory.
 2319  */
 2320 void *
 2321 pmap_mapdev(vm_offset_t pa, vm_size_t size)
 2322 {
 2323         vm_offset_t va, tmpva, ppa, offset;
 2324         int i;
 2325 
 2326         ppa = trunc_page(pa);
 2327         offset = pa & PAGE_MASK;
 2328         size = roundup(offset + size, PAGE_SIZE);
 2329         
 2330         GIANT_REQUIRED;
 2331 
 2332         /*
 2333          * If the physical address lies within a valid BAT table entry,
 2334          * return the 1:1 mapping. This currently doesn't work
 2335          * for regions that overlap 256M BAT segments.
 2336          */
 2337         for (i = 0; i < 16; i++) {
 2338                 if (pmap_bat_mapped(i, pa, size) == 0)
 2339                         return ((void *) pa);
 2340         }
 2341 
 2342         va = kmem_alloc_nofault(kernel_map, size);
 2343         if (!va)
 2344                 panic("pmap_mapdev: Couldn't alloc kernel virtual memory");
 2345 
 2346         for (tmpva = va; size > 0;) {
 2347                 pmap_kenter(tmpva, ppa);
 2348                 TLBIE(tmpva); /* XXX or should it be invalidate-all ? */
 2349                 size -= PAGE_SIZE;
 2350                 tmpva += PAGE_SIZE;
 2351                 ppa += PAGE_SIZE;
 2352         }
 2353 
 2354         return ((void *)(va + offset));
 2355 }
 2356 
 2357 void
 2358 pmap_unmapdev(vm_offset_t va, vm_size_t size)
 2359 {
 2360         vm_offset_t base, offset;
 2361 
 2362         /*
 2363          * If this is outside kernel virtual space, then it's a
 2364          * battable entry and doesn't require unmapping
 2365          */
 2366         if ((va >= VM_MIN_KERNEL_ADDRESS) && (va <= VM_MAX_KERNEL_ADDRESS)) {
 2367                 base = trunc_page(va);
 2368                 offset = va & PAGE_MASK;
 2369                 size = roundup(offset + size, PAGE_SIZE);
 2370                 kmem_free(kernel_map, base, size);
 2371         }
 2372 }

Cache object: a5731269205c8571a0ea75701ddec8bd


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