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.1/sys/powerpc/powerpc/pmap.c 113038 2003-04-03 21:36:33Z obrien $");
   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 <sys/param.h>
  118 #include <sys/kernel.h>
  119 #include <sys/ktr.h>
  120 #include <sys/lock.h>
  121 #include <sys/msgbuf.h>
  122 #include <sys/mutex.h>
  123 #include <sys/proc.h>
  124 #include <sys/sysctl.h>
  125 #include <sys/systm.h>
  126 #include <sys/vmmeter.h>
  127 
  128 #include <dev/ofw/openfirm.h>
  129 
  130 #include <vm/vm.h> 
  131 #include <vm/vm_param.h>
  132 #include <vm/vm_kern.h>
  133 #include <vm/vm_page.h>
  134 #include <vm/vm_map.h>
  135 #include <vm/vm_object.h>
  136 #include <vm/vm_extern.h>
  137 #include <vm/vm_pageout.h>
  138 #include <vm/vm_pager.h>
  139 #include <vm/uma.h>
  140 
  141 #include <machine/powerpc.h>
  142 #include <machine/bat.h>
  143 #include <machine/frame.h>
  144 #include <machine/md_var.h>
  145 #include <machine/psl.h>
  146 #include <machine/pte.h>
  147 #include <machine/sr.h>
  148 
  149 #define PMAP_DEBUG
  150 
  151 #define TODO    panic("%s: not implemented", __func__);
  152 
  153 #define PMAP_LOCK(pm)
  154 #define PMAP_UNLOCK(pm)
  155 
  156 #define TLBIE(va)       __asm __volatile("tlbie %0" :: "r"(va))
  157 #define TLBSYNC()       __asm __volatile("tlbsync");
  158 #define SYNC()          __asm __volatile("sync");
  159 #define EIEIO()         __asm __volatile("eieio");
  160 
  161 #define VSID_MAKE(sr, hash)     ((sr) | (((hash) & 0xfffff) << 4))
  162 #define VSID_TO_SR(vsid)        ((vsid) & 0xf)
  163 #define VSID_TO_HASH(vsid)      (((vsid) >> 4) & 0xfffff)
  164 
  165 #define PVO_PTEGIDX_MASK        0x0007          /* which PTEG slot */
  166 #define PVO_PTEGIDX_VALID       0x0008          /* slot is valid */
  167 #define PVO_WIRED               0x0010          /* PVO entry is wired */
  168 #define PVO_MANAGED             0x0020          /* PVO entry is managed */
  169 #define PVO_EXECUTABLE          0x0040          /* PVO entry is executable */
  170 #define PVO_BOOTSTRAP           0x0080          /* PVO entry allocated during
  171                                                    bootstrap */
  172 #define PVO_VADDR(pvo)          ((pvo)->pvo_vaddr & ~ADDR_POFF)
  173 #define PVO_ISEXECUTABLE(pvo)   ((pvo)->pvo_vaddr & PVO_EXECUTABLE)
  174 #define PVO_PTEGIDX_GET(pvo)    ((pvo)->pvo_vaddr & PVO_PTEGIDX_MASK)
  175 #define PVO_PTEGIDX_ISSET(pvo)  ((pvo)->pvo_vaddr & PVO_PTEGIDX_VALID)
  176 #define PVO_PTEGIDX_CLR(pvo)    \
  177         ((void)((pvo)->pvo_vaddr &= ~(PVO_PTEGIDX_VALID|PVO_PTEGIDX_MASK)))
  178 #define PVO_PTEGIDX_SET(pvo, i) \
  179         ((void)((pvo)->pvo_vaddr |= (i)|PVO_PTEGIDX_VALID))
  180 
  181 #define PMAP_PVO_CHECK(pvo)
  182 
  183 struct ofw_map {
  184         vm_offset_t     om_va;
  185         vm_size_t       om_len;
  186         vm_offset_t     om_pa;
  187         u_int           om_mode;
  188 };
  189 
  190 int     pmap_bootstrapped = 0;
  191 
  192 /*
  193  * Virtual and physical address of message buffer.
  194  */
  195 struct          msgbuf *msgbufp;
  196 vm_offset_t     msgbuf_phys;
  197 
  198 /*
  199  * Physical addresses of first and last available physical page.
  200  */
  201 vm_offset_t avail_start;
  202 vm_offset_t avail_end;
  203 
  204 int pmap_pagedaemon_waken;
  205 
  206 /*
  207  * Map of physical memory regions.
  208  */
  209 vm_offset_t     phys_avail[128];
  210 u_int           phys_avail_count;
  211 static struct   mem_region *regions;
  212 static struct   mem_region *pregions;
  213 int             regions_sz, pregions_sz;
  214 static struct   ofw_map *translations;
  215 
  216 /*
  217  * First and last available kernel virtual addresses.
  218  */
  219 vm_offset_t virtual_avail;
  220 vm_offset_t virtual_end;
  221 vm_offset_t kernel_vm_end;
  222 
  223 /*
  224  * Kernel pmap.
  225  */
  226 struct pmap kernel_pmap_store;
  227 extern struct pmap ofw_pmap;
  228 
  229 /*
  230  * PTEG data.
  231  */
  232 static struct   pteg *pmap_pteg_table;
  233 u_int           pmap_pteg_count;
  234 u_int           pmap_pteg_mask;
  235 
  236 /*
  237  * PVO data.
  238  */
  239 struct  pvo_head *pmap_pvo_table;               /* pvo entries by pteg index */
  240 struct  pvo_head pmap_pvo_kunmanaged =
  241     LIST_HEAD_INITIALIZER(pmap_pvo_kunmanaged); /* list of unmanaged pages */
  242 struct  pvo_head pmap_pvo_unmanaged =
  243     LIST_HEAD_INITIALIZER(pmap_pvo_unmanaged);  /* list of unmanaged pages */
  244 
  245 uma_zone_t      pmap_upvo_zone; /* zone for pvo entries for unmanaged pages */
  246 uma_zone_t      pmap_mpvo_zone; /* zone for pvo entries for managed pages */
  247 struct          vm_object pmap_upvo_zone_obj;
  248 struct          vm_object pmap_mpvo_zone_obj;
  249 static vm_object_t      pmap_pvo_obj;
  250 static u_int            pmap_pvo_count;
  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_offset_t
 1036 pmap_extract(pmap_t pm, vm_offset_t va)
 1037 {
 1038         struct  pvo_entry *pvo;
 1039 
 1040         pvo = pmap_pvo_find_va(pm, va & ~ADDR_POFF, NULL);
 1041 
 1042         if (pvo != NULL) {
 1043                 return ((pvo->pvo_pte.pte_lo & PTE_RPGN) | (va & ADDR_POFF));
 1044         }
 1045 
 1046         return (0);
 1047 }
 1048 
 1049 /*
 1050  * Grow the number of kernel page table entries.  Unneeded.
 1051  */
 1052 void
 1053 pmap_growkernel(vm_offset_t addr)
 1054 {
 1055 }
 1056 
 1057 void
 1058 pmap_init(vm_offset_t phys_start, vm_offset_t phys_end)
 1059 {
 1060 
 1061         CTR0(KTR_PMAP, "pmap_init");
 1062 
 1063         pmap_pvo_obj = vm_object_allocate(OBJT_PHYS, 16);
 1064         pmap_pvo_count = 0;
 1065         pmap_upvo_zone = uma_zcreate("UPVO entry", sizeof (struct pvo_entry),
 1066             NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_VM);
 1067         uma_zone_set_allocf(pmap_upvo_zone, pmap_pvo_allocf);
 1068         pmap_mpvo_zone = uma_zcreate("MPVO entry", sizeof(struct pvo_entry),
 1069             NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_VM);
 1070         uma_zone_set_allocf(pmap_mpvo_zone, pmap_pvo_allocf);
 1071         pmap_initialized = TRUE;
 1072 }
 1073 
 1074 void
 1075 pmap_init2(void)
 1076 {
 1077 
 1078         CTR0(KTR_PMAP, "pmap_init2");
 1079 }
 1080 
 1081 boolean_t
 1082 pmap_is_modified(vm_page_t m)
 1083 {
 1084 
 1085         if ((m->flags & (PG_FICTITIOUS |PG_UNMANAGED)) != 0)
 1086                 return (FALSE);
 1087 
 1088         return (pmap_query_bit(m, PTE_CHG));
 1089 }
 1090 
 1091 void
 1092 pmap_clear_reference(vm_page_t m)
 1093 {
 1094 
 1095         if ((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) != 0)
 1096                 return;
 1097         pmap_clear_bit(m, PTE_REF, NULL);
 1098 }
 1099 
 1100 void
 1101 pmap_clear_modify(vm_page_t m)
 1102 {
 1103 
 1104         if ((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) != 0)
 1105                 return;
 1106         pmap_clear_bit(m, PTE_CHG, NULL);
 1107 }
 1108 
 1109 /*
 1110  *      pmap_ts_referenced:
 1111  *
 1112  *      Return a count of reference bits for a page, clearing those bits.
 1113  *      It is not necessary for every reference bit to be cleared, but it
 1114  *      is necessary that 0 only be returned when there are truly no
 1115  *      reference bits set.
 1116  *
 1117  *      XXX: The exact number of bits to check and clear is a matter that
 1118  *      should be tested and standardized at some point in the future for
 1119  *      optimal aging of shared pages.
 1120  */
 1121 int
 1122 pmap_ts_referenced(vm_page_t m)
 1123 {
 1124         int count;
 1125 
 1126         if ((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) != 0)
 1127                 return (0);
 1128 
 1129         count = pmap_clear_bit(m, PTE_REF, NULL);
 1130 
 1131         return (count);
 1132 }
 1133 
 1134 /*
 1135  * Map a wired page into kernel virtual address space.
 1136  */
 1137 void
 1138 pmap_kenter(vm_offset_t va, vm_offset_t pa)
 1139 {
 1140         u_int           pte_lo;
 1141         int             error;  
 1142         int             i;
 1143 
 1144 #if 0
 1145         if (va < VM_MIN_KERNEL_ADDRESS)
 1146                 panic("pmap_kenter: attempt to enter non-kernel address %#x",
 1147                     va);
 1148 #endif
 1149 
 1150         pte_lo = PTE_I | PTE_G;
 1151         for (i = 0; i < pregions_sz; i++) {
 1152                 if ((pa >= pregions[i].mr_start) &&
 1153                     (pa < (pregions[i].mr_start + pregions[i].mr_size))) {
 1154                         pte_lo &= ~(PTE_I | PTE_G);
 1155                         break;
 1156                 }
 1157         }       
 1158 
 1159         error = pmap_pvo_enter(kernel_pmap, pmap_upvo_zone,
 1160             &pmap_pvo_kunmanaged, va, pa, pte_lo, PVO_WIRED);
 1161 
 1162         if (error != 0 && error != ENOENT)
 1163                 panic("pmap_kenter: failed to enter va %#x pa %#x: %d", va,
 1164                     pa, error);
 1165 
 1166         /*
 1167          * Flush the real memory from the instruction cache.
 1168          */
 1169         if ((pte_lo & (PTE_I | PTE_G)) == 0) {
 1170                 pmap_syncicache(pa, PAGE_SIZE);
 1171         }
 1172 }
 1173 
 1174 /*
 1175  * Extract the physical page address associated with the given kernel virtual
 1176  * address.
 1177  */
 1178 vm_offset_t
 1179 pmap_kextract(vm_offset_t va)
 1180 {
 1181         struct          pvo_entry *pvo;
 1182 
 1183         pvo = pmap_pvo_find_va(kernel_pmap, va & ~ADDR_POFF, NULL);
 1184         if (pvo == NULL) {
 1185                 return (0);
 1186         }
 1187 
 1188         return ((pvo->pvo_pte.pte_lo & PTE_RPGN) | (va & ADDR_POFF));
 1189 }
 1190 
 1191 /*
 1192  * Remove a wired page from kernel virtual address space.
 1193  */
 1194 void
 1195 pmap_kremove(vm_offset_t va)
 1196 {
 1197 
 1198         pmap_remove(kernel_pmap, va, va + PAGE_SIZE);
 1199 }
 1200 
 1201 /*
 1202  * Map a range of physical addresses into kernel virtual address space.
 1203  *
 1204  * The value passed in *virt is a suggested virtual address for the mapping.
 1205  * Architectures which can support a direct-mapped physical to virtual region
 1206  * can return the appropriate address within that region, leaving '*virt'
 1207  * unchanged.  We cannot and therefore do not; *virt is updated with the
 1208  * first usable address after the mapped region.
 1209  */
 1210 vm_offset_t
 1211 pmap_map(vm_offset_t *virt, vm_offset_t pa_start, vm_offset_t pa_end, int prot)
 1212 {
 1213         vm_offset_t     sva, va;
 1214 
 1215         sva = *virt;
 1216         va = sva;
 1217         for (; pa_start < pa_end; pa_start += PAGE_SIZE, va += PAGE_SIZE)
 1218                 pmap_kenter(va, pa_start);
 1219         *virt = va;
 1220         return (sva);
 1221 }
 1222 
 1223 int
 1224 pmap_mincore(pmap_t pmap, vm_offset_t addr)
 1225 {
 1226         TODO;
 1227         return (0);
 1228 }
 1229 
 1230 void
 1231 pmap_object_init_pt(pmap_t pm, vm_offset_t addr, vm_object_t object,
 1232                     vm_pindex_t pindex, vm_size_t size, int limit)
 1233 {
 1234 
 1235         KASSERT(pm == &curproc->p_vmspace->vm_pmap || pm == kernel_pmap,
 1236             ("pmap_remove_pages: non current pmap"));
 1237         /* XXX */
 1238 }
 1239 
 1240 /*
 1241  * Lower the permission for all mappings to a given page.
 1242  */
 1243 void
 1244 pmap_page_protect(vm_page_t m, vm_prot_t prot)
 1245 {
 1246         struct  pvo_head *pvo_head;
 1247         struct  pvo_entry *pvo, *next_pvo;
 1248         struct  pte *pt;
 1249 
 1250         /*
 1251          * Since the routine only downgrades protection, if the
 1252          * maximal protection is desired, there isn't any change
 1253          * to be made.
 1254          */
 1255         if ((prot & (VM_PROT_READ|VM_PROT_WRITE)) ==
 1256             (VM_PROT_READ|VM_PROT_WRITE))
 1257                 return;
 1258 
 1259         pvo_head = vm_page_to_pvoh(m);
 1260         for (pvo = LIST_FIRST(pvo_head); pvo != NULL; pvo = next_pvo) {
 1261                 next_pvo = LIST_NEXT(pvo, pvo_vlink);
 1262                 PMAP_PVO_CHECK(pvo);    /* sanity check */
 1263 
 1264                 /*
 1265                  * Downgrading to no mapping at all, we just remove the entry.
 1266                  */
 1267                 if ((prot & VM_PROT_READ) == 0) {
 1268                         pmap_pvo_remove(pvo, -1);
 1269                         continue;
 1270                 }
 1271 
 1272                 /*
 1273                  * If EXEC permission is being revoked, just clear the flag
 1274                  * in the PVO.
 1275                  */
 1276                 if ((prot & VM_PROT_EXECUTE) == 0)
 1277                         pvo->pvo_vaddr &= ~PVO_EXECUTABLE;
 1278 
 1279                 /*
 1280                  * If this entry is already RO, don't diddle with the page
 1281                  * table.
 1282                  */
 1283                 if ((pvo->pvo_pte.pte_lo & PTE_PP) == PTE_BR) {
 1284                         PMAP_PVO_CHECK(pvo);
 1285                         continue;
 1286                 }
 1287 
 1288                 /*
 1289                  * Grab the PTE before we diddle the bits so pvo_to_pte can
 1290                  * verify the pte contents are as expected.
 1291                  */
 1292                 pt = pmap_pvo_to_pte(pvo, -1);
 1293                 pvo->pvo_pte.pte_lo &= ~PTE_PP;
 1294                 pvo->pvo_pte.pte_lo |= PTE_BR;
 1295                 if (pt != NULL)
 1296                         pmap_pte_change(pt, &pvo->pvo_pte, pvo->pvo_vaddr);
 1297                 PMAP_PVO_CHECK(pvo);    /* sanity check */
 1298         }
 1299 }
 1300 
 1301 /*
 1302  * Returns true if the pmap's pv is one of the first
 1303  * 16 pvs linked to from this page.  This count may
 1304  * be changed upwards or downwards in the future; it
 1305  * is only necessary that true be returned for a small
 1306  * subset of pmaps for proper page aging.
 1307  */
 1308 boolean_t
 1309 pmap_page_exists_quick(pmap_t pmap, vm_page_t m)
 1310 {
 1311         int loops;
 1312         struct pvo_entry *pvo;
 1313 
 1314         if (!pmap_initialized || (m->flags & PG_FICTITIOUS))
 1315                 return FALSE;
 1316 
 1317         loops = 0;
 1318         LIST_FOREACH(pvo, vm_page_to_pvoh(m), pvo_vlink) {
 1319                 if (pvo->pvo_pmap == pmap)
 1320                         return (TRUE);
 1321                 if (++loops >= 16)
 1322                         break;
 1323         }
 1324 
 1325         return (FALSE);
 1326 }
 1327 
 1328 static u_int    pmap_vsidcontext;
 1329 
 1330 void
 1331 pmap_pinit(pmap_t pmap)
 1332 {
 1333         int     i, mask;
 1334         u_int   entropy;
 1335 
 1336         entropy = 0;
 1337         __asm __volatile("mftb %0" : "=r"(entropy));
 1338 
 1339         /*
 1340          * Allocate some segment registers for this pmap.
 1341          */
 1342         for (i = 0; i < NPMAPS; i += VSID_NBPW) {
 1343                 u_int   hash, n;
 1344 
 1345                 /*
 1346                  * Create a new value by mutiplying by a prime and adding in
 1347                  * entropy from the timebase register.  This is to make the
 1348                  * VSID more random so that the PT hash function collides
 1349                  * less often.  (Note that the prime casues gcc to do shifts
 1350                  * instead of a multiply.)
 1351                  */
 1352                 pmap_vsidcontext = (pmap_vsidcontext * 0x1105) + entropy;
 1353                 hash = pmap_vsidcontext & (NPMAPS - 1);
 1354                 if (hash == 0)          /* 0 is special, avoid it */
 1355                         continue;
 1356                 n = hash >> 5;
 1357                 mask = 1 << (hash & (VSID_NBPW - 1));
 1358                 hash = (pmap_vsidcontext & 0xfffff);
 1359                 if (pmap_vsid_bitmap[n] & mask) {       /* collision? */
 1360                         /* anything free in this bucket? */
 1361                         if (pmap_vsid_bitmap[n] == 0xffffffff) {
 1362                                 entropy = (pmap_vsidcontext >> 20);
 1363                                 continue;
 1364                         }
 1365                         i = ffs(~pmap_vsid_bitmap[i]) - 1;
 1366                         mask = 1 << i;
 1367                         hash &= 0xfffff & ~(VSID_NBPW - 1);
 1368                         hash |= i;
 1369                 }
 1370                 pmap_vsid_bitmap[n] |= mask;
 1371                 for (i = 0; i < 16; i++)
 1372                         pmap->pm_sr[i] = VSID_MAKE(i, hash);
 1373                 return;
 1374         }
 1375 
 1376         panic("pmap_pinit: out of segments");
 1377 }
 1378 
 1379 /*
 1380  * Initialize the pmap associated with process 0.
 1381  */
 1382 void
 1383 pmap_pinit0(pmap_t pm)
 1384 {
 1385 
 1386         pmap_pinit(pm);
 1387         bzero(&pm->pm_stats, sizeof(pm->pm_stats));
 1388 }
 1389 
 1390 void
 1391 pmap_pinit2(pmap_t pmap)
 1392 {
 1393         /* XXX: Remove this stub when no longer called */
 1394 }
 1395 
 1396 void
 1397 pmap_prefault(pmap_t pm, vm_offset_t va, vm_map_entry_t entry)
 1398 {
 1399         KASSERT(pm == &curproc->p_vmspace->vm_pmap || pm == kernel_pmap,
 1400             ("pmap_prefault: non current pmap"));
 1401         /* XXX */
 1402 }
 1403 
 1404 /*
 1405  * Set the physical protection on the specified range of this map as requested.
 1406  */
 1407 void
 1408 pmap_protect(pmap_t pm, vm_offset_t sva, vm_offset_t eva, vm_prot_t prot)
 1409 {
 1410         struct  pvo_entry *pvo;
 1411         struct  pte *pt;
 1412         int     pteidx;
 1413 
 1414         CTR4(KTR_PMAP, "pmap_protect: pm=%p sva=%#x eva=%#x prot=%#x", pm, sva,
 1415             eva, prot);
 1416 
 1417 
 1418         KASSERT(pm == &curproc->p_vmspace->vm_pmap || pm == kernel_pmap,
 1419             ("pmap_protect: non current pmap"));
 1420 
 1421         if ((prot & VM_PROT_READ) == VM_PROT_NONE) {
 1422                 pmap_remove(pm, sva, eva);
 1423                 return;
 1424         }
 1425 
 1426         for (; sva < eva; sva += PAGE_SIZE) {
 1427                 pvo = pmap_pvo_find_va(pm, sva, &pteidx);
 1428                 if (pvo == NULL)
 1429                         continue;
 1430 
 1431                 if ((prot & VM_PROT_EXECUTE) == 0)
 1432                         pvo->pvo_vaddr &= ~PVO_EXECUTABLE;
 1433 
 1434                 /*
 1435                  * Grab the PTE pointer before we diddle with the cached PTE
 1436                  * copy.
 1437                  */
 1438                 pt = pmap_pvo_to_pte(pvo, pteidx);
 1439                 /*
 1440                  * Change the protection of the page.
 1441                  */
 1442                 pvo->pvo_pte.pte_lo &= ~PTE_PP;
 1443                 pvo->pvo_pte.pte_lo |= PTE_BR;
 1444 
 1445                 /*
 1446                  * If the PVO is in the page table, update that pte as well.
 1447                  */
 1448                 if (pt != NULL)
 1449                         pmap_pte_change(pt, &pvo->pvo_pte, pvo->pvo_vaddr);
 1450         }
 1451 }
 1452 
 1453 /*
 1454  * Map a list of wired pages into kernel virtual address space.  This is
 1455  * intended for temporary mappings which do not need page modification or
 1456  * references recorded.  Existing mappings in the region are overwritten.
 1457  */
 1458 void
 1459 pmap_qenter(vm_offset_t sva, vm_page_t *m, int count)
 1460 {
 1461         vm_offset_t va;
 1462 
 1463         va = sva;
 1464         while (count-- > 0) {
 1465                 pmap_kenter(va, VM_PAGE_TO_PHYS(*m));
 1466                 va += PAGE_SIZE;
 1467                 m++;
 1468         }
 1469 }
 1470 
 1471 /*
 1472  * Remove page mappings from kernel virtual address space.  Intended for
 1473  * temporary mappings entered by pmap_qenter.
 1474  */
 1475 void
 1476 pmap_qremove(vm_offset_t sva, int count)
 1477 {
 1478         vm_offset_t va;
 1479 
 1480         va = sva;
 1481         while (count-- > 0) {
 1482                 pmap_kremove(va);
 1483                 va += PAGE_SIZE;
 1484         }
 1485 }
 1486 
 1487 void
 1488 pmap_release(pmap_t pmap)
 1489 {
 1490         int idx, mask;
 1491         
 1492         /*
 1493          * Free segment register's VSID
 1494          */
 1495         if (pmap->pm_sr[0] == 0)
 1496                 panic("pmap_release");
 1497 
 1498         idx = VSID_TO_HASH(pmap->pm_sr[0]) & (NPMAPS-1);
 1499         mask = 1 << (idx % VSID_NBPW);
 1500         idx /= VSID_NBPW;
 1501         pmap_vsid_bitmap[idx] &= ~mask;
 1502 }
 1503 
 1504 /*
 1505  * Remove the given range of addresses from the specified map.
 1506  */
 1507 void
 1508 pmap_remove(pmap_t pm, vm_offset_t sva, vm_offset_t eva)
 1509 {
 1510         struct  pvo_entry *pvo;
 1511         int     pteidx;
 1512 
 1513         for (; sva < eva; sva += PAGE_SIZE) {
 1514                 pvo = pmap_pvo_find_va(pm, sva, &pteidx);
 1515                 if (pvo != NULL) {
 1516                         pmap_pvo_remove(pvo, pteidx);
 1517                 }
 1518         }
 1519 }
 1520 
 1521 /*
 1522  * Remove physical page from all pmaps in which it resides. pmap_pvo_remove()
 1523  * will reflect changes in pte's back to the vm_page.
 1524  */
 1525 void
 1526 pmap_remove_all(vm_page_t m)
 1527 {
 1528         struct  pvo_head *pvo_head;
 1529         struct  pvo_entry *pvo, *next_pvo;
 1530 
 1531         KASSERT((m->flags & (PG_FICTITIOUS|PG_UNMANAGED)) == 0,
 1532             ("pv_remove_all: illegal for unmanaged page %#x",
 1533             VM_PAGE_TO_PHYS(m)));
 1534         
 1535         pvo_head = vm_page_to_pvoh(m);
 1536         for (pvo = LIST_FIRST(pvo_head); pvo != NULL; pvo = next_pvo) {
 1537                 next_pvo = LIST_NEXT(pvo, pvo_vlink);
 1538                 
 1539                 PMAP_PVO_CHECK(pvo);    /* sanity check */
 1540                 pmap_pvo_remove(pvo, -1);
 1541         }
 1542         vm_page_flag_clear(m, PG_WRITEABLE);
 1543 }
 1544 
 1545 /*
 1546  * Remove all pages from specified address space, this aids process exit
 1547  * speeds.  This is much faster than pmap_remove in the case of running down
 1548  * an entire address space.  Only works for the current pmap.
 1549  */
 1550 void
 1551 pmap_remove_pages(pmap_t pm, vm_offset_t sva, vm_offset_t eva)
 1552 {
 1553 
 1554         KASSERT(pm == &curproc->p_vmspace->vm_pmap || pm == kernel_pmap,
 1555             ("pmap_remove_pages: non current pmap"));
 1556         pmap_remove(pm, sva, eva);
 1557 }
 1558 
 1559 #ifndef KSTACK_MAX_PAGES
 1560 #define KSTACK_MAX_PAGES 32
 1561 #endif
 1562 
 1563 /*
 1564  * Create the kernel stack and pcb for a new thread.
 1565  * This routine directly affects the fork perf for a process and
 1566  * create performance for a thread.
 1567  */
 1568 void
 1569 pmap_new_thread(struct thread *td, int pages)
 1570 {
 1571         vm_page_t       ma[KSTACK_MAX_PAGES];
 1572         vm_object_t     ksobj;
 1573         vm_offset_t     ks;
 1574         vm_page_t       m;
 1575         u_int           i;
 1576 
 1577         /* Bounds check */
 1578         if (pages <= 1)
 1579                 pages = KSTACK_PAGES; 
 1580         else if (pages > KSTACK_MAX_PAGES)
 1581                 pages = KSTACK_MAX_PAGES;
 1582 
 1583         /*
 1584          * Allocate object for the kstack.
 1585          */
 1586         ksobj = vm_object_allocate(OBJT_DEFAULT, pages);
 1587         td->td_kstack_obj = ksobj;
 1588 
 1589         /*
 1590          * Get a kernel virtual address for the kstack for this thread.
 1591          */
 1592         ks = kmem_alloc_nofault(kernel_map,
 1593             (pages + KSTACK_GUARD_PAGES) * PAGE_SIZE);
 1594         if (ks == 0)
 1595                 panic("pmap_new_thread: kstack allocation failed");
 1596         TLBIE(ks);
 1597         ks += KSTACK_GUARD_PAGES * PAGE_SIZE;
 1598         td->td_kstack = ks;
 1599 
 1600         /*
 1601          * Knowing the number of pages allocated is useful when you
 1602          * want to deallocate them.
 1603          */
 1604         td->td_kstack_pages = pages;
 1605 
 1606         for (i = 0; i < pages; i++) {
 1607                 /*
 1608                  * Get a kernel stack page.
 1609                  */
 1610                 m = vm_page_grab(ksobj, i,
 1611                     VM_ALLOC_NORMAL | VM_ALLOC_RETRY | VM_ALLOC_WIRED);
 1612                 ma[i] = m;
 1613 
 1614                 vm_page_lock_queues();
 1615                 vm_page_wakeup(m);
 1616                 vm_page_flag_clear(m, PG_ZERO);
 1617                 m->valid = VM_PAGE_BITS_ALL;
 1618                 vm_page_unlock_queues();
 1619         }
 1620 
 1621         /*
 1622          * Enter the page into the kernel address space
 1623          */
 1624         pmap_qenter(ks, ma, pages);
 1625 }
 1626 
 1627 void
 1628 pmap_dispose_thread(struct thread *td)
 1629 {
 1630         vm_object_t ksobj;
 1631         vm_offset_t ks;
 1632         vm_page_t m;
 1633         int i;
 1634         int pages;
 1635 
 1636         pages = td->td_kstack_pages;
 1637         ksobj = td->td_kstack_obj;
 1638         ks = td->td_kstack;
 1639         for (i = 0; i < pages ; i++) {
 1640                 m = vm_page_lookup(ksobj, i);
 1641                 if (m == NULL)
 1642                         panic("pmap_dispose_thread: kstack already missing?");
 1643                 vm_page_lock_queues();
 1644                 vm_page_busy(m);
 1645                 vm_page_unwire(m, 0);
 1646                 vm_page_free(m);
 1647                 vm_page_unlock_queues();
 1648         }
 1649         pmap_qremove(ks, pages);
 1650         kmem_free(kernel_map, ks - (KSTACK_GUARD_PAGES * PAGE_SIZE),
 1651            (pages + KSTACK_GUARD_PAGES) * PAGE_SIZE);
 1652         vm_object_deallocate(ksobj);
 1653 }
 1654 
 1655 void
 1656 pmap_new_altkstack(struct thread *td, int pages)
 1657 {
 1658         /* shuffle the original stack */
 1659         td->td_altkstack_obj = td->td_kstack_obj;
 1660         td->td_altkstack = td->td_kstack;
 1661         td->td_altkstack_pages = td->td_kstack_pages;
 1662 
 1663         pmap_new_thread(td, pages);
 1664 }
 1665 
 1666 void
 1667 pmap_dispose_altkstack(struct thread *td)
 1668 {
 1669         pmap_dispose_thread(td);
 1670 
 1671         /* restore the original kstack */
 1672         td->td_kstack = td->td_altkstack;
 1673         td->td_kstack_obj = td->td_altkstack_obj;
 1674         td->td_kstack_pages = td->td_altkstack_pages;
 1675         td->td_altkstack = 0;
 1676         td->td_altkstack_obj = NULL;
 1677         td->td_altkstack_pages = 0;
 1678 }
 1679 
 1680 void
 1681 pmap_swapin_thread(struct thread *td)
 1682 {
 1683         vm_page_t ma[KSTACK_MAX_PAGES];
 1684         vm_object_t ksobj;
 1685         vm_offset_t ks;
 1686         vm_page_t m;
 1687         int rv;
 1688         int i;
 1689         int pages;
 1690 
 1691         pages = td->td_kstack_pages;
 1692         ksobj = td->td_kstack_obj;
 1693         ks = td->td_kstack;
 1694         for (i = 0; i < pages; i++) {
 1695                 m = vm_page_grab(ksobj, i, VM_ALLOC_NORMAL | VM_ALLOC_RETRY);
 1696                 if (m->valid != VM_PAGE_BITS_ALL) {
 1697                         rv = vm_pager_get_pages(ksobj, &m, 1, 0);
 1698                         if (rv != VM_PAGER_OK)
 1699                                 panic("pmap_swapin_thread: cannot get kstack");
 1700                         m = vm_page_lookup(ksobj, i);
 1701                         m->valid = VM_PAGE_BITS_ALL;
 1702                 }
 1703                 ma[i] = m;
 1704                 vm_page_lock_queues();
 1705                 vm_page_wire(m);
 1706                 vm_page_wakeup(m);
 1707                 vm_page_unlock_queues();
 1708         }
 1709         pmap_qenter(ks, ma, pages);
 1710 }
 1711 
 1712 
 1713 void
 1714 pmap_swapout_thread(struct thread *td)
 1715 {
 1716         vm_object_t ksobj;
 1717         vm_offset_t ks;
 1718         vm_page_t m;
 1719         int i;
 1720         int pages;
 1721 
 1722         pages = td->td_kstack_pages;
 1723         ksobj = td->td_kstack_obj;
 1724         ks = (vm_offset_t)td->td_kstack;
 1725         for (i = 0; i < pages; i++) {
 1726                 m = vm_page_lookup(ksobj, i);
 1727                 if (m == NULL)
 1728                         panic("pmap_swapout_thread: kstack already missing?");
 1729                 vm_page_lock_queues();
 1730                 vm_page_dirty(m);
 1731                 vm_page_unwire(m, 0);
 1732                 vm_page_unlock_queues();
 1733         }
 1734         pmap_qremove(ks, pages);
 1735 }
 1736 
 1737 /*
 1738  * Allocate a physical page of memory directly from the phys_avail map.
 1739  * Can only be called from pmap_bootstrap before avail start and end are
 1740  * calculated.
 1741  */
 1742 static vm_offset_t
 1743 pmap_bootstrap_alloc(vm_size_t size, u_int align)
 1744 {
 1745         vm_offset_t     s, e;
 1746         int             i, j;
 1747 
 1748         size = round_page(size);
 1749         for (i = 0; phys_avail[i + 1] != 0; i += 2) {
 1750                 if (align != 0)
 1751                         s = (phys_avail[i] + align - 1) & ~(align - 1);
 1752                 else
 1753                         s = phys_avail[i];
 1754                 e = s + size;
 1755 
 1756                 if (s < phys_avail[i] || e > phys_avail[i + 1])
 1757                         continue;
 1758 
 1759                 if (s == phys_avail[i]) {
 1760                         phys_avail[i] += size;
 1761                 } else if (e == phys_avail[i + 1]) {
 1762                         phys_avail[i + 1] -= size;
 1763                 } else {
 1764                         for (j = phys_avail_count * 2; j > i; j -= 2) {
 1765                                 phys_avail[j] = phys_avail[j - 2];
 1766                                 phys_avail[j + 1] = phys_avail[j - 1];
 1767                         }
 1768 
 1769                         phys_avail[i + 3] = phys_avail[i + 1];
 1770                         phys_avail[i + 1] = s;
 1771                         phys_avail[i + 2] = e;
 1772                         phys_avail_count++;
 1773                 }
 1774 
 1775                 return (s);
 1776         }
 1777         panic("pmap_bootstrap_alloc: could not allocate memory");
 1778 }
 1779 
 1780 /*
 1781  * Return an unmapped pvo for a kernel virtual address.
 1782  * Used by pmap functions that operate on physical pages.
 1783  */
 1784 static struct pvo_entry *
 1785 pmap_rkva_alloc(void)
 1786 {
 1787         struct          pvo_entry *pvo;
 1788         struct          pte *pt;
 1789         vm_offset_t     kva;
 1790         int             pteidx;
 1791 
 1792         if (pmap_rkva_count == 0)
 1793                 panic("pmap_rkva_alloc: no more reserved KVAs");
 1794 
 1795         kva = pmap_rkva_start + (PAGE_SIZE * --pmap_rkva_count);
 1796         pmap_kenter(kva, 0);
 1797 
 1798         pvo = pmap_pvo_find_va(kernel_pmap, kva, &pteidx);
 1799 
 1800         if (pvo == NULL)
 1801                 panic("pmap_kva_alloc: pmap_pvo_find_va failed");
 1802 
 1803         pt = pmap_pvo_to_pte(pvo, pteidx);
 1804 
 1805         if (pt == NULL)
 1806                 panic("pmap_kva_alloc: pmap_pvo_to_pte failed");
 1807 
 1808         pmap_pte_unset(pt, &pvo->pvo_pte, pvo->pvo_vaddr);
 1809         PVO_PTEGIDX_CLR(pvo);
 1810 
 1811         pmap_pte_overflow++;
 1812 
 1813         return (pvo);
 1814 }
 1815 
 1816 static void
 1817 pmap_pa_map(struct pvo_entry *pvo, vm_offset_t pa, struct pte *saved_pt,
 1818     int *depth_p)
 1819 {
 1820         struct  pte *pt;
 1821 
 1822         /*
 1823          * If this pvo already has a valid pte, we need to save it so it can
 1824          * be restored later.  We then just reload the new PTE over the old
 1825          * slot.
 1826          */
 1827         if (saved_pt != NULL) {
 1828                 pt = pmap_pvo_to_pte(pvo, -1);
 1829 
 1830                 if (pt != NULL) {
 1831                         pmap_pte_unset(pt, &pvo->pvo_pte, pvo->pvo_vaddr);
 1832                         PVO_PTEGIDX_CLR(pvo);
 1833                         pmap_pte_overflow++;
 1834                 }
 1835 
 1836                 *saved_pt = pvo->pvo_pte;
 1837 
 1838                 pvo->pvo_pte.pte_lo &= ~PTE_RPGN;
 1839         }
 1840 
 1841         pvo->pvo_pte.pte_lo |= pa;
 1842 
 1843         if (!pmap_pte_spill(pvo->pvo_vaddr))
 1844                 panic("pmap_pa_map: could not spill pvo %p", pvo);
 1845 
 1846         if (depth_p != NULL)
 1847                 (*depth_p)++;
 1848 }
 1849 
 1850 static void
 1851 pmap_pa_unmap(struct pvo_entry *pvo, struct pte *saved_pt, int *depth_p)
 1852 {
 1853         struct  pte *pt;
 1854 
 1855         pt = pmap_pvo_to_pte(pvo, -1);
 1856 
 1857         if (pt != NULL) {
 1858                 pmap_pte_unset(pt, &pvo->pvo_pte, pvo->pvo_vaddr);
 1859                 PVO_PTEGIDX_CLR(pvo);
 1860                 pmap_pte_overflow++;
 1861         }
 1862 
 1863         pvo->pvo_pte.pte_lo &= ~PTE_RPGN;
 1864 
 1865         /*
 1866          * If there is a saved PTE and it's valid, restore it and return.
 1867          */
 1868         if (saved_pt != NULL && (saved_pt->pte_lo & PTE_RPGN) != 0) {
 1869                 if (depth_p != NULL && --(*depth_p) == 0)
 1870                         panic("pmap_pa_unmap: restoring but depth == 0");
 1871 
 1872                 pvo->pvo_pte = *saved_pt;
 1873 
 1874                 if (!pmap_pte_spill(pvo->pvo_vaddr))
 1875                         panic("pmap_pa_unmap: could not spill pvo %p", pvo);
 1876         }
 1877 }
 1878 
 1879 static void
 1880 pmap_syncicache(vm_offset_t pa, vm_size_t len)
 1881 {
 1882         __syncicache((void *)pa, len);
 1883 }
 1884 
 1885 static void
 1886 tlbia(void)
 1887 {
 1888         caddr_t i;
 1889 
 1890         SYNC();
 1891         for (i = 0; i < (caddr_t)0x00040000; i += 0x00001000) {
 1892                 TLBIE(i);
 1893                 EIEIO();
 1894         }
 1895         TLBSYNC();
 1896         SYNC();
 1897 }
 1898 
 1899 static int
 1900 pmap_pvo_enter(pmap_t pm, uma_zone_t zone, struct pvo_head *pvo_head,
 1901     vm_offset_t va, vm_offset_t pa, u_int pte_lo, int flags)
 1902 {
 1903         struct  pvo_entry *pvo;
 1904         u_int   sr;
 1905         int     first;
 1906         u_int   ptegidx;
 1907         int     i;
 1908         int     bootstrap;
 1909 
 1910         pmap_pvo_enter_calls++;
 1911         first = 0;
 1912         
 1913         bootstrap = 0;
 1914 
 1915         /*
 1916          * Compute the PTE Group index.
 1917          */
 1918         va &= ~ADDR_POFF;
 1919         sr = va_to_sr(pm->pm_sr, va);
 1920         ptegidx = va_to_pteg(sr, va);
 1921 
 1922         /*
 1923          * Remove any existing mapping for this page.  Reuse the pvo entry if
 1924          * there is a mapping.
 1925          */
 1926         LIST_FOREACH(pvo, &pmap_pvo_table[ptegidx], pvo_olink) {
 1927                 if (pvo->pvo_pmap == pm && PVO_VADDR(pvo) == va) {
 1928                         if ((pvo->pvo_pte.pte_lo & PTE_RPGN) == pa &&
 1929                             (pvo->pvo_pte.pte_lo & PTE_PP) ==
 1930                             (pte_lo & PTE_PP)) {
 1931                                 return (0);
 1932                         }
 1933                         pmap_pvo_remove(pvo, -1);
 1934                         break;
 1935                 }
 1936         }
 1937 
 1938         /*
 1939          * If we aren't overwriting a mapping, try to allocate.
 1940          */
 1941         if (pmap_initialized) {
 1942                 pvo = uma_zalloc(zone, M_NOWAIT);
 1943         } else {
 1944                 if (pmap_bpvo_pool_index >= BPVO_POOL_SIZE) {
 1945                         panic("pmap_enter: bpvo pool exhausted, %d, %d, %d",
 1946                               pmap_bpvo_pool_index, BPVO_POOL_SIZE, 
 1947                               BPVO_POOL_SIZE * sizeof(struct pvo_entry));
 1948                 }
 1949                 pvo = &pmap_bpvo_pool[pmap_bpvo_pool_index];
 1950                 pmap_bpvo_pool_index++;
 1951                 bootstrap = 1;
 1952         }
 1953 
 1954         if (pvo == NULL) {
 1955                 return (ENOMEM);
 1956         }
 1957 
 1958         pmap_pvo_entries++;
 1959         pvo->pvo_vaddr = va;
 1960         pvo->pvo_pmap = pm;
 1961         LIST_INSERT_HEAD(&pmap_pvo_table[ptegidx], pvo, pvo_olink);
 1962         pvo->pvo_vaddr &= ~ADDR_POFF;
 1963         if (flags & VM_PROT_EXECUTE)
 1964                 pvo->pvo_vaddr |= PVO_EXECUTABLE;
 1965         if (flags & PVO_WIRED)
 1966                 pvo->pvo_vaddr |= PVO_WIRED;
 1967         if (pvo_head != &pmap_pvo_kunmanaged)
 1968                 pvo->pvo_vaddr |= PVO_MANAGED;
 1969         if (bootstrap)
 1970                 pvo->pvo_vaddr |= PVO_BOOTSTRAP;
 1971         pmap_pte_create(&pvo->pvo_pte, sr, va, pa | pte_lo);
 1972 
 1973         /*
 1974          * Remember if the list was empty and therefore will be the first
 1975          * item.
 1976          */
 1977         if (LIST_FIRST(pvo_head) == NULL)
 1978                 first = 1;
 1979 
 1980         LIST_INSERT_HEAD(pvo_head, pvo, pvo_vlink);
 1981         if (pvo->pvo_pte.pte_lo & PVO_WIRED)
 1982                 pvo->pvo_pmap->pm_stats.wired_count++;
 1983         pvo->pvo_pmap->pm_stats.resident_count++;
 1984 
 1985         /*
 1986          * We hope this succeeds but it isn't required.
 1987          */
 1988         i = pmap_pte_insert(ptegidx, &pvo->pvo_pte);
 1989         if (i >= 0) {
 1990                 PVO_PTEGIDX_SET(pvo, i);
 1991         } else {
 1992                 panic("pmap_pvo_enter: overflow");
 1993                 pmap_pte_overflow++;
 1994         }
 1995 
 1996         return (first ? ENOENT : 0);
 1997 }
 1998 
 1999 static void
 2000 pmap_pvo_remove(struct pvo_entry *pvo, int pteidx)
 2001 {
 2002         struct  pte *pt;
 2003 
 2004         /*
 2005          * If there is an active pte entry, we need to deactivate it (and
 2006          * save the ref & cfg bits).
 2007          */
 2008         pt = pmap_pvo_to_pte(pvo, pteidx);
 2009         if (pt != NULL) {
 2010                 pmap_pte_unset(pt, &pvo->pvo_pte, pvo->pvo_vaddr);
 2011                 PVO_PTEGIDX_CLR(pvo);
 2012         } else {
 2013                 pmap_pte_overflow--;
 2014         }       
 2015 
 2016         /*
 2017          * Update our statistics.
 2018          */
 2019         pvo->pvo_pmap->pm_stats.resident_count--;
 2020         if (pvo->pvo_pte.pte_lo & PVO_WIRED)
 2021                 pvo->pvo_pmap->pm_stats.wired_count--;
 2022 
 2023         /*
 2024          * Save the REF/CHG bits into their cache if the page is managed.
 2025          */
 2026         if (pvo->pvo_vaddr & PVO_MANAGED) {
 2027                 struct  vm_page *pg;
 2028 
 2029                 pg = PHYS_TO_VM_PAGE(pvo->pvo_pte.pte_lo & PTE_RPGN);
 2030                 if (pg != NULL) {
 2031                         pmap_attr_save(pg, pvo->pvo_pte.pte_lo &
 2032                             (PTE_REF | PTE_CHG));
 2033                 }
 2034         }
 2035 
 2036         /*
 2037          * Remove this PVO from the PV list.
 2038          */
 2039         LIST_REMOVE(pvo, pvo_vlink);
 2040 
 2041         /*
 2042          * Remove this from the overflow list and return it to the pool
 2043          * if we aren't going to reuse it.
 2044          */
 2045         LIST_REMOVE(pvo, pvo_olink);
 2046         if (!(pvo->pvo_vaddr & PVO_BOOTSTRAP))
 2047                 uma_zfree(pvo->pvo_vaddr & PVO_MANAGED ? pmap_mpvo_zone :
 2048                     pmap_upvo_zone, pvo);
 2049         pmap_pvo_entries--;
 2050         pmap_pvo_remove_calls++;
 2051 }
 2052 
 2053 static __inline int
 2054 pmap_pvo_pte_index(const struct pvo_entry *pvo, int ptegidx)
 2055 {
 2056         int     pteidx;
 2057 
 2058         /*
 2059          * We can find the actual pte entry without searching by grabbing
 2060          * the PTEG index from 3 unused bits in pte_lo[11:9] and by
 2061          * noticing the HID bit.
 2062          */
 2063         pteidx = ptegidx * 8 + PVO_PTEGIDX_GET(pvo);
 2064         if (pvo->pvo_pte.pte_hi & PTE_HID)
 2065                 pteidx ^= pmap_pteg_mask * 8;
 2066 
 2067         return (pteidx);
 2068 }
 2069 
 2070 static struct pvo_entry *
 2071 pmap_pvo_find_va(pmap_t pm, vm_offset_t va, int *pteidx_p)
 2072 {
 2073         struct  pvo_entry *pvo;
 2074         int     ptegidx;
 2075         u_int   sr;
 2076 
 2077         va &= ~ADDR_POFF;
 2078         sr = va_to_sr(pm->pm_sr, va);
 2079         ptegidx = va_to_pteg(sr, va);
 2080 
 2081         LIST_FOREACH(pvo, &pmap_pvo_table[ptegidx], pvo_olink) {
 2082                 if (pvo->pvo_pmap == pm && PVO_VADDR(pvo) == va) {
 2083                         if (pteidx_p)
 2084                                 *pteidx_p = pmap_pvo_pte_index(pvo, ptegidx);
 2085                         return (pvo);
 2086                 }
 2087         }
 2088 
 2089         return (NULL);
 2090 }
 2091 
 2092 static struct pte *
 2093 pmap_pvo_to_pte(const struct pvo_entry *pvo, int pteidx)
 2094 {
 2095         struct  pte *pt;
 2096 
 2097         /*
 2098          * If we haven't been supplied the ptegidx, calculate it.
 2099          */
 2100         if (pteidx == -1) {
 2101                 int     ptegidx;
 2102                 u_int   sr;
 2103 
 2104                 sr = va_to_sr(pvo->pvo_pmap->pm_sr, pvo->pvo_vaddr);
 2105                 ptegidx = va_to_pteg(sr, pvo->pvo_vaddr);
 2106                 pteidx = pmap_pvo_pte_index(pvo, ptegidx);
 2107         }
 2108 
 2109         pt = &pmap_pteg_table[pteidx >> 3].pt[pteidx & 7];
 2110 
 2111         if ((pvo->pvo_pte.pte_hi & PTE_VALID) && !PVO_PTEGIDX_ISSET(pvo)) {
 2112                 panic("pmap_pvo_to_pte: pvo %p has valid pte in pvo but no "
 2113                     "valid pte index", pvo);
 2114         }
 2115 
 2116         if ((pvo->pvo_pte.pte_hi & PTE_VALID) == 0 && PVO_PTEGIDX_ISSET(pvo)) {
 2117                 panic("pmap_pvo_to_pte: pvo %p has valid pte index in pvo "
 2118                     "pvo but no valid pte", pvo);
 2119         }
 2120 
 2121         if ((pt->pte_hi ^ (pvo->pvo_pte.pte_hi & ~PTE_VALID)) == PTE_VALID) {
 2122                 if ((pvo->pvo_pte.pte_hi & PTE_VALID) == 0) {
 2123                         panic("pmap_pvo_to_pte: pvo %p has valid pte in "
 2124                             "pmap_pteg_table %p but invalid in pvo", pvo, pt);
 2125                 }
 2126 
 2127                 if (((pt->pte_lo ^ pvo->pvo_pte.pte_lo) & ~(PTE_CHG|PTE_REF))
 2128                     != 0) {
 2129                         panic("pmap_pvo_to_pte: pvo %p pte does not match "
 2130                             "pte %p in pmap_pteg_table", pvo, pt);
 2131                 }
 2132 
 2133                 return (pt);
 2134         }
 2135 
 2136         if (pvo->pvo_pte.pte_hi & PTE_VALID) {
 2137                 panic("pmap_pvo_to_pte: pvo %p has invalid pte %p in "
 2138                     "pmap_pteg_table but valid in pvo", pvo, pt);
 2139         }
 2140 
 2141         return (NULL);
 2142 }
 2143 
 2144 static void *
 2145 pmap_pvo_allocf(uma_zone_t zone, int bytes, u_int8_t *flags, int wait)
 2146 {
 2147         vm_page_t       m;
 2148 
 2149         if (bytes != PAGE_SIZE)
 2150                 panic("pmap_pvo_allocf: benno was shortsighted.  hit him.");
 2151 
 2152         *flags = UMA_SLAB_PRIV;
 2153         m = vm_page_alloc(pmap_pvo_obj, pmap_pvo_count, VM_ALLOC_SYSTEM);
 2154         if (m == NULL)
 2155                 return (NULL);
 2156         pmap_pvo_count++;
 2157         return ((void *)VM_PAGE_TO_PHYS(m));
 2158 }
 2159 
 2160 /*
 2161  * XXX: THIS STUFF SHOULD BE IN pte.c?
 2162  */
 2163 int
 2164 pmap_pte_spill(vm_offset_t addr)
 2165 {
 2166         struct  pvo_entry *source_pvo, *victim_pvo;
 2167         struct  pvo_entry *pvo;
 2168         int     ptegidx, i, j;
 2169         u_int   sr;
 2170         struct  pteg *pteg;
 2171         struct  pte *pt;
 2172 
 2173         pmap_pte_spills++;
 2174 
 2175         sr = mfsrin(addr);
 2176         ptegidx = va_to_pteg(sr, addr);
 2177 
 2178         /*
 2179          * Have to substitute some entry.  Use the primary hash for this.
 2180          * Use low bits of timebase as random generator.
 2181          */
 2182         pteg = &pmap_pteg_table[ptegidx];
 2183         __asm __volatile("mftb %0" : "=r"(i));
 2184         i &= 7;
 2185         pt = &pteg->pt[i];
 2186 
 2187         source_pvo = NULL;
 2188         victim_pvo = NULL;
 2189         LIST_FOREACH(pvo, &pmap_pvo_table[ptegidx], pvo_olink) {
 2190                 /*
 2191                  * We need to find a pvo entry for this address.
 2192                  */
 2193                 PMAP_PVO_CHECK(pvo);
 2194                 if (source_pvo == NULL &&
 2195                     pmap_pte_match(&pvo->pvo_pte, sr, addr,
 2196                     pvo->pvo_pte.pte_hi & PTE_HID)) {
 2197                         /*
 2198                          * Now found an entry to be spilled into the pteg.
 2199                          * The PTE is now valid, so we know it's active.
 2200                          */
 2201                         j = pmap_pte_insert(ptegidx, &pvo->pvo_pte);
 2202 
 2203                         if (j >= 0) {
 2204                                 PVO_PTEGIDX_SET(pvo, j);
 2205                                 pmap_pte_overflow--;
 2206                                 PMAP_PVO_CHECK(pvo);
 2207                                 return (1);
 2208                         }
 2209 
 2210                         source_pvo = pvo;
 2211 
 2212                         if (victim_pvo != NULL)
 2213                                 break;
 2214                 }
 2215 
 2216                 /*
 2217                  * We also need the pvo entry of the victim we are replacing
 2218                  * so save the R & C bits of the PTE.
 2219                  */
 2220                 if ((pt->pte_hi & PTE_HID) == 0 && victim_pvo == NULL &&
 2221                     pmap_pte_compare(pt, &pvo->pvo_pte)) {
 2222                         victim_pvo = pvo;
 2223                         if (source_pvo != NULL)
 2224                                 break;
 2225                 }
 2226         }
 2227 
 2228         if (source_pvo == NULL)
 2229                 return (0);
 2230 
 2231         if (victim_pvo == NULL) {
 2232                 if ((pt->pte_hi & PTE_HID) == 0)
 2233                         panic("pmap_pte_spill: victim p-pte (%p) has no pvo"
 2234                             "entry", pt);
 2235 
 2236                 /*
 2237                  * If this is a secondary PTE, we need to search it's primary
 2238                  * pvo bucket for the matching PVO.
 2239                  */
 2240                 LIST_FOREACH(pvo, &pmap_pvo_table[ptegidx ^ pmap_pteg_mask],
 2241                     pvo_olink) {
 2242                         PMAP_PVO_CHECK(pvo);
 2243                         /*
 2244                          * We also need the pvo entry of the victim we are
 2245                          * replacing so save the R & C bits of the PTE.
 2246                          */
 2247                         if (pmap_pte_compare(pt, &pvo->pvo_pte)) {
 2248                                 victim_pvo = pvo;
 2249                                 break;
 2250                         }
 2251                 }
 2252 
 2253                 if (victim_pvo == NULL)
 2254                         panic("pmap_pte_spill: victim s-pte (%p) has no pvo"
 2255                             "entry", pt);
 2256         }
 2257 
 2258         /*
 2259          * We are invalidating the TLB entry for the EA we are replacing even
 2260          * though it's valid.  If we don't, we lose any ref/chg bit changes
 2261          * contained in the TLB entry.
 2262          */
 2263         source_pvo->pvo_pte.pte_hi &= ~PTE_HID;
 2264 
 2265         pmap_pte_unset(pt, &victim_pvo->pvo_pte, victim_pvo->pvo_vaddr);
 2266         pmap_pte_set(pt, &source_pvo->pvo_pte);
 2267 
 2268         PVO_PTEGIDX_CLR(victim_pvo);
 2269         PVO_PTEGIDX_SET(source_pvo, i);
 2270         pmap_pte_replacements++;
 2271 
 2272         PMAP_PVO_CHECK(victim_pvo);
 2273         PMAP_PVO_CHECK(source_pvo);
 2274 
 2275         return (1);
 2276 }
 2277 
 2278 static int
 2279 pmap_pte_insert(u_int ptegidx, struct pte *pvo_pt)
 2280 {
 2281         struct  pte *pt;
 2282         int     i;
 2283 
 2284         /*
 2285          * First try primary hash.
 2286          */
 2287         for (pt = pmap_pteg_table[ptegidx].pt, i = 0; i < 8; i++, pt++) {
 2288                 if ((pt->pte_hi & PTE_VALID) == 0) {
 2289                         pvo_pt->pte_hi &= ~PTE_HID;
 2290                         pmap_pte_set(pt, pvo_pt);
 2291                         return (i);
 2292                 }
 2293         }
 2294 
 2295         /*
 2296          * Now try secondary hash.
 2297          */
 2298         ptegidx ^= pmap_pteg_mask;
 2299         ptegidx++;
 2300         for (pt = pmap_pteg_table[ptegidx].pt, i = 0; i < 8; i++, pt++) {
 2301                 if ((pt->pte_hi & PTE_VALID) == 0) {
 2302                         pvo_pt->pte_hi |= PTE_HID;
 2303                         pmap_pte_set(pt, pvo_pt);
 2304                         return (i);
 2305                 }
 2306         }
 2307 
 2308         panic("pmap_pte_insert: overflow");
 2309         return (-1);
 2310 }
 2311 
 2312 static boolean_t
 2313 pmap_query_bit(vm_page_t m, int ptebit)
 2314 {
 2315         struct  pvo_entry *pvo;
 2316         struct  pte *pt;
 2317 
 2318         if (pmap_attr_fetch(m) & ptebit)
 2319                 return (TRUE);
 2320 
 2321         LIST_FOREACH(pvo, vm_page_to_pvoh(m), pvo_vlink) {
 2322                 PMAP_PVO_CHECK(pvo);    /* sanity check */
 2323 
 2324                 /*
 2325                  * See if we saved the bit off.  If so, cache it and return
 2326                  * success.
 2327                  */
 2328                 if (pvo->pvo_pte.pte_lo & ptebit) {
 2329                         pmap_attr_save(m, ptebit);
 2330                         PMAP_PVO_CHECK(pvo);    /* sanity check */
 2331                         return (TRUE);
 2332                 }
 2333         }
 2334 
 2335         /*
 2336          * No luck, now go through the hard part of looking at the PTEs
 2337          * themselves.  Sync so that any pending REF/CHG bits are flushed to
 2338          * the PTEs.
 2339          */
 2340         SYNC();
 2341         LIST_FOREACH(pvo, vm_page_to_pvoh(m), pvo_vlink) {
 2342                 PMAP_PVO_CHECK(pvo);    /* sanity check */
 2343 
 2344                 /*
 2345                  * See if this pvo has a valid PTE.  if so, fetch the
 2346                  * REF/CHG bits from the valid PTE.  If the appropriate
 2347                  * ptebit is set, cache it and return success.
 2348                  */
 2349                 pt = pmap_pvo_to_pte(pvo, -1);
 2350                 if (pt != NULL) {
 2351                         pmap_pte_synch(pt, &pvo->pvo_pte);
 2352                         if (pvo->pvo_pte.pte_lo & ptebit) {
 2353                                 pmap_attr_save(m, ptebit);
 2354                                 PMAP_PVO_CHECK(pvo);    /* sanity check */
 2355                                 return (TRUE);
 2356                         }
 2357                 }
 2358         }
 2359 
 2360         return (TRUE);
 2361 }
 2362 
 2363 static u_int
 2364 pmap_clear_bit(vm_page_t m, int ptebit, int *origbit)
 2365 {
 2366         u_int   count;
 2367         struct  pvo_entry *pvo;
 2368         struct  pte *pt;
 2369         int     rv;
 2370 
 2371         /*
 2372          * Clear the cached value.
 2373          */
 2374         rv = pmap_attr_fetch(m);
 2375         pmap_attr_clear(m, ptebit);
 2376 
 2377         /*
 2378          * Sync so that any pending REF/CHG bits are flushed to the PTEs (so
 2379          * we can reset the right ones).  note that since the pvo entries and
 2380          * list heads are accessed via BAT0 and are never placed in the page
 2381          * table, we don't have to worry about further accesses setting the
 2382          * REF/CHG bits.
 2383          */
 2384         SYNC();
 2385 
 2386         /*
 2387          * For each pvo entry, clear the pvo's ptebit.  If this pvo has a
 2388          * valid pte clear the ptebit from the valid pte.
 2389          */
 2390         count = 0;
 2391         LIST_FOREACH(pvo, vm_page_to_pvoh(m), pvo_vlink) {
 2392                 PMAP_PVO_CHECK(pvo);    /* sanity check */
 2393                 pt = pmap_pvo_to_pte(pvo, -1);
 2394                 if (pt != NULL) {
 2395                         pmap_pte_synch(pt, &pvo->pvo_pte);
 2396                         if (pvo->pvo_pte.pte_lo & ptebit) {
 2397                                 count++;
 2398                                 pmap_pte_clear(pt, PVO_VADDR(pvo), ptebit);
 2399                         }
 2400                 }
 2401                 rv |= pvo->pvo_pte.pte_lo;
 2402                 pvo->pvo_pte.pte_lo &= ~ptebit;
 2403                 PMAP_PVO_CHECK(pvo);    /* sanity check */
 2404         }
 2405 
 2406         if (origbit != NULL) {
 2407                 *origbit = rv;
 2408         }
 2409 
 2410         return (count);
 2411 }
 2412 
 2413 /*
 2414  * Return true if the physical range is encompassed by the battable[idx]
 2415  */
 2416 static int
 2417 pmap_bat_mapped(int idx, vm_offset_t pa, vm_size_t size)
 2418 {
 2419         u_int prot;
 2420         u_int32_t start;
 2421         u_int32_t end;
 2422         u_int32_t bat_ble;
 2423 
 2424         /*
 2425          * Return immediately if not a valid mapping
 2426          */
 2427         if (!battable[idx].batu & BAT_Vs)
 2428                 return (EINVAL);
 2429 
 2430         /*
 2431          * The BAT entry must be cache-inhibited, guarded, and r/w
 2432          * so it can function as an i/o page
 2433          */
 2434         prot = battable[idx].batl & (BAT_I|BAT_G|BAT_PP_RW);
 2435         if (prot != (BAT_I|BAT_G|BAT_PP_RW))
 2436                 return (EPERM); 
 2437 
 2438         /*
 2439          * The address should be within the BAT range. Assume that the
 2440          * start address in the BAT has the correct alignment (thus
 2441          * not requiring masking)
 2442          */
 2443         start = battable[idx].batl & BAT_PBS;
 2444         bat_ble = (battable[idx].batu & ~(BAT_EBS)) | 0x03;
 2445         end = start | (bat_ble << 15) | 0x7fff;
 2446 
 2447         if ((pa < start) || ((pa + size) > end))
 2448                 return (ERANGE);
 2449 
 2450         return (0);
 2451 }
 2452 
 2453 
 2454 /*
 2455  * Map a set of physical memory pages into the kernel virtual
 2456  * address space. Return a pointer to where it is mapped. This
 2457  * routine is intended to be used for mapping device memory,
 2458  * NOT real memory.
 2459  */
 2460 void *
 2461 pmap_mapdev(vm_offset_t pa, vm_size_t size)
 2462 {
 2463         vm_offset_t va, tmpva, ppa, offset;
 2464         int i;
 2465 
 2466         ppa = trunc_page(pa);
 2467         offset = pa & PAGE_MASK;
 2468         size = roundup(offset + size, PAGE_SIZE);
 2469         
 2470         GIANT_REQUIRED;
 2471 
 2472         /*
 2473          * If the physical address lies within a valid BAT table entry,
 2474          * return the 1:1 mapping. This currently doesn't work
 2475          * for regions that overlap 256M BAT segments.
 2476          */
 2477         for (i = 0; i < 16; i++) {
 2478                 if (pmap_bat_mapped(i, pa, size) == 0)
 2479                         return ((void *) pa);
 2480         }
 2481 
 2482         va = kmem_alloc_pageable(kernel_map, size);
 2483         if (!va)
 2484                 panic("pmap_mapdev: Couldn't alloc kernel virtual memory");
 2485 
 2486         for (tmpva = va; size > 0;) {
 2487                 pmap_kenter(tmpva, ppa);
 2488                 TLBIE(tmpva); /* XXX or should it be invalidate-all ? */
 2489                 size -= PAGE_SIZE;
 2490                 tmpva += PAGE_SIZE;
 2491                 ppa += PAGE_SIZE;
 2492         }
 2493 
 2494         return ((void *)(va + offset));
 2495 }
 2496 
 2497 void
 2498 pmap_unmapdev(vm_offset_t va, vm_size_t size)
 2499 {
 2500         vm_offset_t base, offset;
 2501 
 2502         /*
 2503          * If this is outside kernel virtual space, then it's a
 2504          * battable entry and doesn't require unmapping
 2505          */
 2506         if ((va >= VM_MIN_KERNEL_ADDRESS) && (va <= VM_MAX_KERNEL_ADDRESS)) {
 2507                 base = trunc_page(va);
 2508                 offset = va & PAGE_MASK;
 2509                 size = roundup(offset + size, PAGE_SIZE);
 2510                 kmem_free(kernel_map, base, size);
 2511         }
 2512 }

Cache object: 09dd846743ed309ce34d26643e420e97


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