[BACK]Return to pmap.c CVS log [TXT][DIR] Up to [local] / sys / arch / alpha / alpha

Annotation of sys/arch/alpha/alpha/pmap.c, Revision 1.1.1.1

1.1       nbrk        1: /* $OpenBSD: pmap.c,v 1.52 2007/05/26 20:26:50 pedro Exp $ */
                      2: /* $NetBSD: pmap.c,v 1.154 2000/12/07 22:18:55 thorpej Exp $ */
                      3:
                      4: /*-
                      5:  * Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
                      6:  * All rights reserved.
                      7:  *
                      8:  * This code is derived from software contributed to The NetBSD Foundation
                      9:  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
                     10:  * NASA Ames Research Center and by Chris G. Demetriou.
                     11:  *
                     12:  * Redistribution and use in source and binary forms, with or without
                     13:  * modification, are permitted provided that the following conditions
                     14:  * are met:
                     15:  * 1. Redistributions of source code must retain the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer.
                     17:  * 2. Redistributions in binary form must reproduce the above copyright
                     18:  *    notice, this list of conditions and the following disclaimer in the
                     19:  *    documentation and/or other materials provided with the distribution.
                     20:  * 3. All advertising materials mentioning features or use of this software
                     21:  *    must display the following acknowledgement:
                     22:  *     This product includes software developed by the NetBSD
                     23:  *     Foundation, Inc. and its contributors.
                     24:  * 4. Neither the name of The NetBSD Foundation nor the names of its
                     25:  *    contributors may be used to endorse or promote products derived
                     26:  *    from this software without specific prior written permission.
                     27:  *
                     28:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     29:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     30:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     31:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     32:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     33:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     34:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     35:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     36:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     37:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     38:  * POSSIBILITY OF SUCH DAMAGE.
                     39:  */
                     40:
                     41: /*
                     42:  * Copyright (c) 1991, 1993
                     43:  *     The Regents of the University of California.  All rights reserved.
                     44:  *
                     45:  * This code is derived from software contributed to Berkeley by
                     46:  * the Systems Programming Group of the University of Utah Computer
                     47:  * Science Department.
                     48:  *
                     49:  * Redistribution and use in source and binary forms, with or without
                     50:  * modification, are permitted provided that the following conditions
                     51:  * are met:
                     52:  * 1. Redistributions of source code must retain the above copyright
                     53:  *    notice, this list of conditions and the following disclaimer.
                     54:  * 2. Redistributions in binary form must reproduce the above copyright
                     55:  *    notice, this list of conditions and the following disclaimer in the
                     56:  *    documentation and/or other materials provided with the distribution.
                     57:  * 3. Neither the name of the University nor the names of its contributors
                     58:  *    may be used to endorse or promote products derived from this software
                     59:  *    without specific prior written permission.
                     60:  *
                     61:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     62:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     63:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     64:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     65:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     66:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     67:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     68:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     69:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     70:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     71:  * SUCH DAMAGE.
                     72:  *
                     73:  *     @(#)pmap.c      8.6 (Berkeley) 5/27/94
                     74:  */
                     75:
                     76: /*
                     77:  * DEC Alpha physical map management code.
                     78:  *
                     79:  * History:
                     80:  *
                     81:  *     This pmap started life as a Motorola 68851/68030 pmap,
                     82:  *     written by Mike Hibler at the University of Utah.
                     83:  *
                     84:  *     It was modified for the DEC Alpha by Chris Demetriou
                     85:  *     at Carnegie Mellon University.
                     86:  *
                     87:  *     Support for non-contiguous physical memory was added by
                     88:  *     Jason R. Thorpe of the Numerical Aerospace Simulation
                     89:  *     Facility, NASA Ames Research Center and Chris Demetriou.
                     90:  *
                     91:  *     Page table management and a major cleanup were undertaken
                     92:  *     by Jason R. Thorpe, with lots of help from Ross Harvey of
                     93:  *     Avalon Computer Systems and from Chris Demetriou.
                     94:  *
                     95:  *     Support for the new UVM pmap interface was written by
                     96:  *     Jason R. Thorpe.
                     97:  *
                     98:  *     Support for ASNs was written by Jason R. Thorpe, again
                     99:  *     with help from Chris Demetriou and Ross Harvey.
                    100:  *
                    101:  *     The locking protocol was written by Jason R. Thorpe,
                    102:  *     using Chuck Cranor's i386 pmap for UVM as a model.
                    103:  *
                    104:  *     TLB shootdown code was written by Jason R. Thorpe.
                    105:  *
                    106:  * Notes:
                    107:  *
                    108:  *     All page table access is done via K0SEG.  The one exception
                    109:  *     to this is for kernel mappings.  Since all kernel page
                    110:  *     tables are pre-allocated, we can use the Virtual Page Table
                    111:  *     to access PTEs that map K1SEG addresses.
                    112:  *
                    113:  *     Kernel page table pages are statically allocated in
                    114:  *     pmap_bootstrap(), and are never freed.  In the future,
                    115:  *     support for dynamically adding additional kernel page
                    116:  *     table pages may be added.  User page table pages are
                    117:  *     dynamically allocated and freed.
                    118:  *
                    119:  * Bugs/misfeatures:
                    120:  *
                    121:  *     - Some things could be optimized.
                    122:  */
                    123:
                    124: /*
                    125:  *     Manages physical address maps.
                    126:  *
                    127:  *     Since the information managed by this module is
                    128:  *     also stored by the logical address mapping module,
                    129:  *     this module may throw away valid virtual-to-physical
                    130:  *     mappings at almost any time.  However, invalidations
                    131:  *     of virtual-to-physical mappings must be done as
                    132:  *     requested.
                    133:  *
                    134:  *     In order to cope with hardware architectures which
                    135:  *     make virtual-to-physical map invalidates expensive,
                    136:  *     this module may delay invalidate or reduced protection
                    137:  *     operations until such time as they are actually
                    138:  *     necessary.  This module is given full information as
                    139:  *     to which processors are currently using which maps,
                    140:  *     and to when physical maps must be made correct.
                    141:  */
                    142:
                    143: #include <sys/param.h>
                    144: #include <sys/systm.h>
                    145: #include <sys/proc.h>
                    146: #include <sys/malloc.h>
                    147: #include <sys/pool.h>
                    148: #include <sys/user.h>
                    149: #include <sys/buf.h>
                    150: #ifdef SYSVSHM
                    151: #include <sys/shm.h>
                    152: #endif
                    153:
                    154: #include <uvm/uvm.h>
                    155:
                    156: #include <machine/atomic.h>
                    157: #include <machine/cpu.h>
                    158: #if defined(_PMAP_MAY_USE_PROM_CONSOLE) || defined(MULTIPROCESSOR)
                    159: #include <machine/rpb.h>
                    160: #endif
                    161:
                    162: #ifdef DEBUG
                    163: #define        PDB_FOLLOW      0x0001
                    164: #define        PDB_INIT        0x0002
                    165: #define        PDB_ENTER       0x0004
                    166: #define        PDB_REMOVE      0x0008
                    167: #define        PDB_CREATE      0x0010
                    168: #define        PDB_PTPAGE      0x0020
                    169: #define        PDB_ASN         0x0040
                    170: #define        PDB_BITS        0x0080
                    171: #define        PDB_COLLECT     0x0100
                    172: #define        PDB_PROTECT     0x0200
                    173: #define        PDB_BOOTSTRAP   0x1000
                    174: #define        PDB_PARANOIA    0x2000
                    175: #define        PDB_WIRING      0x4000
                    176: #define        PDB_PVDUMP      0x8000
                    177:
                    178: int debugmap = 0;
                    179: int pmapdebug = PDB_PARANOIA|PDB_FOLLOW|PDB_ENTER;
                    180: #endif
                    181:
                    182: /*
                    183:  * Given a map and a machine independent protection code,
                    184:  * convert to an alpha protection code.
                    185:  */
                    186: #define pte_prot(m, p) (protection_codes[m == pmap_kernel() ? 0 : 1][p])
                    187: int    protection_codes[2][8];
                    188:
                    189: /*
                    190:  * kernel_lev1map:
                    191:  *
                    192:  *     Kernel level 1 page table.  This maps all kernel level 2
                    193:  *     page table pages, and is used as a template for all user
                    194:  *     pmap level 1 page tables.  When a new user level 1 page
                    195:  *     table is allocated, all kernel_lev1map PTEs for kernel
                    196:  *     addresses are copied to the new map.
                    197:  *
                    198:  *     The kernel also has an initial set of kernel level 2 page
                    199:  *     table pages.  These map the kernel level 3 page table pages.
                    200:  *     As kernel level 3 page table pages are added, more level 2
                    201:  *     page table pages may be added to map them.  These pages are
                    202:  *     never freed.
                    203:  *
                    204:  *     Finally, the kernel also has an initial set of kernel level
                    205:  *     3 page table pages.  These map pages in K1SEG.  More level
                    206:  *     3 page table pages may be added at run-time if additional
                    207:  *     K1SEG address space is required.  These pages are never freed.
                    208:  *
                    209:  * NOTE: When mappings are inserted into the kernel pmap, all
                    210:  * level 2 and level 3 page table pages must already be allocated
                    211:  * and mapped into the parent page table.
                    212:  */
                    213: pt_entry_t     *kernel_lev1map;
                    214:
                    215: /*
                    216:  * Virtual Page Table.
                    217:  */
                    218: pt_entry_t     *VPT;
                    219:
                    220: struct pmap    kernel_pmap_store;
                    221: u_int          kernel_pmap_asn_store[ALPHA_MAXPROCS];
                    222: u_long         kernel_pmap_asngen_store[ALPHA_MAXPROCS];
                    223:
                    224: paddr_t        avail_start;    /* PA of first available physical page */
                    225: paddr_t                avail_end;      /* PA of last available physical page */
                    226: vaddr_t                virtual_avail;  /* VA of first avail page (after kernel bss)*/
                    227: vaddr_t                virtual_end;    /* VA of last avail page (end of kernel AS) */
                    228:
                    229: boolean_t      pmap_initialized;       /* Has pmap_init completed? */
                    230:
                    231: u_long         pmap_pages_stolen;      /* instrumentation */
                    232:
                    233: /*
                    234:  * This variable contains the number of CPU IDs we need to allocate
                    235:  * space for when allocating the pmap structure.  It is used to
                    236:  * size a per-CPU array of ASN and ASN Generation number.
                    237:  */
                    238: u_long         pmap_ncpuids;
                    239:
                    240: /*
                    241:  * Storage for physical->virtual entries and page attributes.
                    242:  */
                    243: struct pv_head *pv_table;
                    244: int            pv_table_npages;
                    245:
                    246: #ifndef PMAP_PV_LOWAT
                    247: #define        PMAP_PV_LOWAT   16
                    248: #endif
                    249: int            pmap_pv_lowat = PMAP_PV_LOWAT;
                    250:
                    251: /*
                    252:  * List of all pmaps, used to update them when e.g. additional kernel
                    253:  * page tables are allocated.  This list is kept LRU-ordered by
                    254:  * pmap_activate().
                    255:  */
                    256: TAILQ_HEAD(, pmap) pmap_all_pmaps;
                    257:
                    258: /*
                    259:  * The pools from which pmap structures and sub-structures are allocated.
                    260:  */
                    261: struct pool pmap_pmap_pool;
                    262: struct pool pmap_l1pt_pool;
                    263: struct pool_cache pmap_l1pt_cache;
                    264: struct pool pmap_asn_pool;
                    265: struct pool pmap_asngen_pool;
                    266: struct pool pmap_pv_pool;
                    267:
                    268: /*
                    269:  * Canonical names for PGU_* constants.
                    270:  */
                    271: const char *pmap_pgu_strings[] = PGU_STRINGS;
                    272:
                    273: /*
                    274:  * Address Space Numbers.
                    275:  *
                    276:  * On many implementations of the Alpha architecture, the TLB entries and
                    277:  * I-cache blocks are tagged with a unique number within an implementation-
                    278:  * specified range.  When a process context becomes active, the ASN is used
                    279:  * to match TLB entries; if a TLB entry for a particular VA does not match
                    280:  * the current ASN, it is ignored (one could think of the processor as
                    281:  * having a collection of <max ASN> separate TLBs).  This allows operating
                    282:  * system software to skip the TLB flush that would otherwise be necessary
                    283:  * at context switch time.
                    284:  *
                    285:  * Alpha PTEs have a bit in them (PG_ASM - Address Space Match) that
                    286:  * causes TLB entries to match any ASN.  The PALcode also provides
                    287:  * a TBI (Translation Buffer Invalidate) operation that flushes all
                    288:  * TLB entries that _do not_ have PG_ASM.  We use this bit for kernel
                    289:  * mappings, so that invalidation of all user mappings does not invalidate
                    290:  * kernel mappings (which are consistent across all processes).
                    291:  *
                    292:  * pmap_next_asn always indicates to the next ASN to use.  When
                    293:  * pmap_next_asn exceeds pmap_max_asn, we start a new ASN generation.
                    294:  *
                    295:  * When a new ASN generation is created, the per-process (i.e. non-PG_ASM)
                    296:  * TLB entries and the I-cache are flushed, the generation number is bumped,
                    297:  * and pmap_next_asn is changed to indicate the first non-reserved ASN.
                    298:  *
                    299:  * We reserve ASN #0 for pmaps that use the global kernel_lev1map.  This
                    300:  * prevents the following scenario:
                    301:  *
                    302:  *     * New ASN generation starts, and process A is given ASN #0.
                    303:  *
                    304:  *     * A new process B (and thus new pmap) is created.  The ASN,
                    305:  *       for lack of a better value, is initialized to 0.
                    306:  *
                    307:  *     * Process B runs.  It is now using the TLB entries tagged
                    308:  *       by process A.  *poof*
                    309:  *
                    310:  * In the scenario above, in addition to the processor using using incorrect
                    311:  * TLB entries, the PALcode might use incorrect information to service a
                    312:  * TLB miss.  (The PALcode uses the recursively mapped Virtual Page Table
                    313:  * to locate the PTE for a faulting address, and tagged TLB entries exist
                    314:  * for the Virtual Page Table addresses in order to speed up this procedure,
                    315:  * as well.)
                    316:  *
                    317:  * By reserving an ASN for kernel_lev1map users, we are guaranteeing that
                    318:  * new pmaps will initially run with no TLB entries for user addresses
                    319:  * or VPT mappings that map user page tables.  Since kernel_lev1map only
                    320:  * contains mappings for kernel addresses, and since those mappings
                    321:  * are always made with PG_ASM, sharing an ASN for kernel_lev1map users is
                    322:  * safe (since PG_ASM mappings match any ASN).
                    323:  *
                    324:  * On processors that do not support ASNs, the PALcode invalidates
                    325:  * the TLB and I-cache automatically on swpctx.  We still still go
                    326:  * through the motions of assigning an ASN (really, just refreshing
                    327:  * the ASN generation in this particular case) to keep the logic sane
                    328:  * in other parts of the code.
                    329:  */
                    330: u_int  pmap_max_asn;                   /* max ASN supported by the system */
                    331: u_int  pmap_next_asn[ALPHA_MAXPROCS];  /* next free ASN to use */
                    332: u_long pmap_asn_generation[ALPHA_MAXPROCS]; /* current ASN generation */
                    333:
                    334: /*
                    335:  * Locking:
                    336:  *
                    337:  *     This pmap module uses two types of locks: `normal' (sleep)
                    338:  *     locks and `simple' (spin) locks.  They are used as follows:
                    339:  *
                    340:  *     SIMPLE LOCKS
                    341:  *     ------------
                    342:  *
                    343:  *     * pm_slock (per-pmap) - This lock protects all of the members
                    344:  *       of the pmap structure itself.  This lock will be asserted
                    345:  *       in pmap_activate() and pmap_deactivate() from a critical
                    346:  *       section of cpu_switch(), and must never sleep.  Note that
                    347:  *       in the case of the kernel pmap, interrupts which cause
                    348:  *       memory allocation *must* be blocked while this lock is
                    349:  *       asserted.
                    350:  *
                    351:  *     * pvh_slock (per-pv_head) - This lock protects the PV list
                    352:  *       for a specified managed page.
                    353:  *
                    354:  *     * pmap_all_pmaps_slock - This lock protects the global list of
                    355:  *       all pmaps.  Note that a pm_slock must never be held while this
                    356:  *       lock is held.
                    357:  *
                    358:  *     * pmap_growkernel_slock - This lock protects pmap_growkernel()
                    359:  *       and the virtual_end variable.
                    360:  *
                    361:  *     Address space number management (global ASN counters and per-pmap
                    362:  *     ASN state) are not locked; they use arrays of values indexed
                    363:  *     per-processor.
                    364:  *
                    365:  *     All internal functions which operate on a pmap are called
                    366:  *     with the pmap already locked by the caller (which will be
                    367:  *     an interface function).
                    368:  */
                    369: struct simplelock pmap_all_pmaps_slock;
                    370: struct simplelock pmap_growkernel_slock;
                    371:
                    372: #define        PMAP_MAP_TO_HEAD_LOCK()         /* nothing */
                    373: #define        PMAP_MAP_TO_HEAD_UNLOCK()       /* nothing */
                    374: #define        PMAP_HEAD_TO_MAP_LOCK()         /* nothing */
                    375: #define        PMAP_HEAD_TO_MAP_UNLOCK()       /* nothing */
                    376:
                    377: #if defined(MULTIPROCESSOR)
                    378: /*
                    379:  * TLB Shootdown:
                    380:  *
                    381:  * When a mapping is changed in a pmap, the TLB entry corresponding to
                    382:  * the virtual address must be invalidated on all processors.  In order
                    383:  * to accomplish this on systems with multiple processors, messages are
                    384:  * sent from the processor which performs the mapping change to all
                    385:  * processors on which the pmap is active.  For other processors, the
                    386:  * ASN generation numbers for that processor is invalidated, so that
                    387:  * the next time the pmap is activated on that processor, a new ASN
                    388:  * will be allocated (which implicitly invalidates all TLB entries).
                    389:  *
                    390:  * Note, we can use the pool allocator to allocate job entries
                    391:  * since pool pages are mapped with K0SEG, not with the TLB.
                    392:  */
                    393: struct pmap_tlb_shootdown_job {
                    394:        TAILQ_ENTRY(pmap_tlb_shootdown_job) pj_list;
                    395:        vaddr_t pj_va;                  /* virtual address */
                    396:        pmap_t pj_pmap;                 /* the pmap which maps the address */
                    397:        pt_entry_t pj_pte;              /* the PTE bits */
                    398: };
                    399:
                    400: struct pmap_tlb_shootdown_q {
                    401:        TAILQ_HEAD(, pmap_tlb_shootdown_job) pq_head;
                    402:        int pq_pte;                     /* aggregate PTE bits */
                    403:        int pq_count;                   /* number of pending requests */
                    404:        struct simplelock pq_slock;     /* spin lock on queue */
                    405: } pmap_tlb_shootdown_q[ALPHA_MAXPROCS];
                    406:
                    407: #define        PSJQ_LOCK(pq, s)                                                \
                    408: do {                                                                   \
                    409:        s = splvm();                                                    \
                    410:        simple_lock(&(pq)->pq_slock);                                   \
                    411: } while (0)
                    412:
                    413: #define        PSJQ_UNLOCK(pq, s)                                              \
                    414: do {                                                                   \
                    415:        simple_unlock(&(pq)->pq_slock);                                 \
                    416:        splx(s);                                                        \
                    417: } while (0)
                    418:
                    419: /* If we have more pending jobs than this, we just nail the whole TLB. */
                    420: #define        PMAP_TLB_SHOOTDOWN_MAXJOBS      6
                    421:
                    422: struct pool pmap_tlb_shootdown_job_pool;
                    423:
                    424: struct pmap_tlb_shootdown_job *pmap_tlb_shootdown_job_get
                    425:            (struct pmap_tlb_shootdown_q *);
                    426: void   pmap_tlb_shootdown_job_put(struct pmap_tlb_shootdown_q *,
                    427:            struct pmap_tlb_shootdown_job *);
                    428: #endif /* MULTIPROCESSOR */
                    429:
                    430: #define        PAGE_IS_MANAGED(pa)     (vm_physseg_find(atop(pa), NULL) != -1)
                    431:
                    432: static __inline struct pv_head *
                    433: pa_to_pvh(paddr_t pa)
                    434: {
                    435:        int bank, pg;
                    436:
                    437:        bank = vm_physseg_find(atop(pa), &pg);
                    438:        return (&vm_physmem[bank].pmseg.pvhead[pg]);
                    439: }
                    440:
                    441: /*
                    442:  * Optional argument passed to pmap_remove_mapping() for stealing mapping
                    443:  * resources.
                    444:  */
                    445: struct prm_thief {
                    446:        int     prmt_flags;             /* flags; what to steal */
                    447:        struct pv_entry *prmt_pv;       /* the stolen PV entry */
                    448:        pt_entry_t *prmt_ptp;           /* the stolen PT page */
                    449: };
                    450:
                    451: #define        PRMT_PV         0x0001          /* steal the PV entry */
                    452: #define        PRMT_PTP        0x0002          /* steal the PT page */
                    453:
                    454: /*
                    455:  * Internal routines
                    456:  */
                    457: void   alpha_protection_init(void);
                    458: void   pmap_do_remove(pmap_t, vaddr_t, vaddr_t, boolean_t);
                    459: boolean_t pmap_remove_mapping(pmap_t, vaddr_t, pt_entry_t *,
                    460:            boolean_t, cpuid_t, struct prm_thief *);
                    461: void   pmap_changebit(paddr_t, pt_entry_t, pt_entry_t, cpuid_t);
                    462:
                    463: /*
                    464:  * PT page management functions.
                    465:  */
                    466: int    pmap_lev1map_create(pmap_t, cpuid_t);
                    467: void   pmap_lev1map_destroy(pmap_t, cpuid_t);
                    468: int    pmap_ptpage_alloc(pmap_t, pt_entry_t *, int);
                    469: boolean_t pmap_ptpage_steal(pmap_t, int, paddr_t *);
                    470: void   pmap_ptpage_free(pmap_t, pt_entry_t *, pt_entry_t **);
                    471: void   pmap_l3pt_delref(pmap_t, vaddr_t, pt_entry_t *, cpuid_t,
                    472:            pt_entry_t **);
                    473: void   pmap_l2pt_delref(pmap_t, pt_entry_t *, pt_entry_t *, cpuid_t);
                    474: void   pmap_l1pt_delref(pmap_t, pt_entry_t *, cpuid_t);
                    475:
                    476: void   *pmap_l1pt_alloc(struct pool *, int);
                    477: void   pmap_l1pt_free(struct pool *, void *);
                    478:
                    479: struct pool_allocator pmap_l1pt_allocator = {
                    480:        pmap_l1pt_alloc, pmap_l1pt_free, 0,
                    481: };
                    482:
                    483: int    pmap_l1pt_ctor(void *, void *, int);
                    484:
                    485: /*
                    486:  * PV table management functions.
                    487:  */
                    488: int    pmap_pv_enter(pmap_t, paddr_t, vaddr_t, pt_entry_t *, boolean_t);
                    489: void   pmap_pv_remove(pmap_t, paddr_t, vaddr_t, boolean_t,
                    490:            struct pv_entry **);
                    491: struct pv_entry *pmap_pv_alloc(void);
                    492: void   pmap_pv_free(struct pv_entry *);
                    493: void   *pmap_pv_page_alloc(struct pool *, int);
                    494: void   pmap_pv_page_free(struct pool *, void *);
                    495: struct pool_allocator pmap_pv_allocator = {
                    496:        pmap_pv_page_alloc, pmap_pv_page_free, 0,
                    497: };
                    498: #ifdef DEBUG
                    499: void   pmap_pv_dump(paddr_t);
                    500: #endif
                    501:
                    502: /*
                    503:  * ASN management functions.
                    504:  */
                    505: void   pmap_asn_alloc(pmap_t, cpuid_t);
                    506:
                    507: /*
                    508:  * Misc. functions.
                    509:  */
                    510: boolean_t pmap_physpage_alloc(int, paddr_t *);
                    511: void   pmap_physpage_free(paddr_t);
                    512: int    pmap_physpage_addref(void *);
                    513: int    pmap_physpage_delref(void *);
                    514:
                    515: /*
                    516:  * PMAP_ISACTIVE{,_TEST}:
                    517:  *
                    518:  *     Check to see if a pmap is active on the current processor.
                    519:  */
                    520: #define        PMAP_ISACTIVE_TEST(pm, cpu_id)                                  \
                    521:        (((pm)->pm_cpus & (1UL << (cpu_id))) != 0)
                    522:
                    523: #if defined(DEBUG) && !defined(MULTIPROCESSOR)
                    524: #define        PMAP_ISACTIVE(pm, cpu_id)                                       \
                    525: ({                                                                     \
                    526:        /*                                                              \
                    527:         * XXX This test is not MP-safe.                                \
                    528:         */                                                             \
                    529:        int isactive_ = PMAP_ISACTIVE_TEST(pm, cpu_id);                 \
                    530:                                                                        \
                    531:        if (curproc != NULL && curproc->p_vmspace != NULL &&            \
                    532:            (pm) != pmap_kernel() &&                                    \
                    533:            (isactive_ ^ ((pm) == curproc->p_vmspace->vm_map.pmap)))    \
                    534:                panic("PMAP_ISACTIVE, isa: %d pm: %p curpm:%p",         \
                    535:                    isactive_, (pm), curproc->p_vmspace->vm_map.pmap);  \
                    536:        (isactive_);                                                    \
                    537: })
                    538: #else
                    539: #define        PMAP_ISACTIVE(pm, cpu_id)       PMAP_ISACTIVE_TEST(pm, cpu_id)
                    540: #endif /* DEBUG && !MULTIPROCESSOR */
                    541:
                    542: /*
                    543:  * PMAP_ACTIVATE_ASN_SANITY:
                    544:  *
                    545:  *     DEBUG sanity checks for ASNs within PMAP_ACTIVATE.
                    546:  */
                    547: #ifdef DEBUG
                    548: #define        PMAP_ACTIVATE_ASN_SANITY(pmap, cpu_id)                          \
                    549: do {                                                                   \
                    550:        if ((pmap)->pm_lev1map == kernel_lev1map) {                     \
                    551:                /*                                                      \
                    552:                 * This pmap implementation also ensures that pmaps     \
                    553:                 * referencing kernel_lev1map use a reserved ASN        \
                    554:                 * ASN to prevent the PALcode from servicing a TLB      \
                    555:                 * miss with the wrong PTE.                             \
                    556:                 */                                                     \
                    557:                if ((pmap)->pm_asn[(cpu_id)] != PMAP_ASN_RESERVED) {    \
                    558:                        printf("kernel_lev1map with non-reserved ASN "  \
                    559:                            "(line %d)\n", __LINE__);                   \
                    560:                        panic("PMAP_ACTIVATE_ASN_SANITY");              \
                    561:                }                                                       \
                    562:        } else {                                                        \
                    563:                if ((pmap)->pm_asngen[(cpu_id)] !=                      \
                    564:                    pmap_asn_generation[(cpu_id)]) {                    \
                    565:                        /*                                              \
                    566:                         * ASN generation number isn't valid!           \
                    567:                         */                                             \
                    568:                        printf("pmap asngen %lu, current %lu "          \
                    569:                            "(line %d)\n",                              \
                    570:                            (pmap)->pm_asngen[(cpu_id)],                \
                    571:                            pmap_asn_generation[(cpu_id)],              \
                    572:                            __LINE__);                                  \
                    573:                        panic("PMAP_ACTIVATE_ASN_SANITY");              \
                    574:                }                                                       \
                    575:                if ((pmap)->pm_asn[(cpu_id)] == PMAP_ASN_RESERVED) {    \
                    576:                        /*                                              \
                    577:                         * DANGER WILL ROBINSON!  We're going to        \
                    578:                         * pollute the VPT TLB entries!                 \
                    579:                         */                                             \
                    580:                        printf("Using reserved ASN! (line %d)\n",       \
                    581:                            __LINE__);                                  \
                    582:                        panic("PMAP_ACTIVATE_ASN_SANITY");              \
                    583:                }                                                       \
                    584:        }                                                               \
                    585: } while (0)
                    586: #else
                    587: #define        PMAP_ACTIVATE_ASN_SANITY(pmap, cpu_id)  /* nothing */
                    588: #endif
                    589:
                    590: /*
                    591:  * PMAP_ACTIVATE:
                    592:  *
                    593:  *     This is essentially the guts of pmap_activate(), without
                    594:  *     ASN allocation.  This is used by pmap_activate(),
                    595:  *     pmap_lev1map_create(), and pmap_lev1map_destroy().
                    596:  *
                    597:  *     This is called only when it is known that a pmap is "active"
                    598:  *     on the current processor; the ASN must already be valid.
                    599:  */
                    600: #define        PMAP_ACTIVATE(pmap, p, cpu_id)                                  \
                    601: do {                                                                   \
                    602:        PMAP_ACTIVATE_ASN_SANITY(pmap, cpu_id);                         \
                    603:                                                                        \
                    604:        (p)->p_addr->u_pcb.pcb_hw.apcb_ptbr =                           \
                    605:            ALPHA_K0SEG_TO_PHYS((vaddr_t)(pmap)->pm_lev1map) >> PGSHIFT; \
                    606:        (p)->p_addr->u_pcb.pcb_hw.apcb_asn = (pmap)->pm_asn[(cpu_id)];  \
                    607:                                                                        \
                    608:        if ((p) == curproc) {                                           \
                    609:                /*                                                      \
                    610:                 * Page table base register has changed; switch to      \
                    611:                 * our own context again so that it will take effect.   \
                    612:                 */                                                     \
                    613:                (void) alpha_pal_swpctx((u_long)p->p_md.md_pcbpaddr);   \
                    614:        }                                                               \
                    615: } while (0)
                    616:
                    617: /*
                    618:  * PMAP_SET_NEEDISYNC:
                    619:  *
                    620:  *     Mark that a user pmap needs an I-stream synch on its
                    621:  *     way back out to userspace.
                    622:  */
                    623: #define        PMAP_SET_NEEDISYNC(pmap)        (pmap)->pm_needisync = ~0UL
                    624:
                    625: /*
                    626:  * PMAP_SYNC_ISTREAM:
                    627:  *
                    628:  *     Synchronize the I-stream for the specified pmap.  For user
                    629:  *     pmaps, this is deferred until a process using the pmap returns
                    630:  *     to userspace.
                    631:  */
                    632: #if defined(MULTIPROCESSOR)
                    633: #define        PMAP_SYNC_ISTREAM_KERNEL()                                      \
                    634: do {                                                                   \
                    635:        alpha_pal_imb();                                                \
                    636:        alpha_broadcast_ipi(ALPHA_IPI_IMB);                             \
                    637: } while (0)
                    638:
                    639: #define        PMAP_SYNC_ISTREAM_USER(pmap)                                    \
                    640: do {                                                                   \
                    641:        alpha_multicast_ipi((pmap)->pm_cpus, ALPHA_IPI_AST);            \
                    642:        /* for curcpu, will happen in userret() */                      \
                    643: } while (0)
                    644: #else
                    645: #define        PMAP_SYNC_ISTREAM_KERNEL()      alpha_pal_imb()
                    646: #define        PMAP_SYNC_ISTREAM_USER(pmap)    /* will happen in userret() */
                    647: #endif /* MULTIPROCESSOR */
                    648:
                    649: #define        PMAP_SYNC_ISTREAM(pmap)                                         \
                    650: do {                                                                   \
                    651:        if ((pmap) == pmap_kernel())                                    \
                    652:                PMAP_SYNC_ISTREAM_KERNEL();                             \
                    653:        else                                                            \
                    654:                PMAP_SYNC_ISTREAM_USER(pmap);                           \
                    655: } while (0)
                    656:
                    657: /*
                    658:  * PMAP_INVALIDATE_ASN:
                    659:  *
                    660:  *     Invalidate the specified pmap's ASN, so as to force allocation
                    661:  *     of a new one the next time pmap_asn_alloc() is called.
                    662:  *
                    663:  *     NOTE: THIS MUST ONLY BE CALLED IF AT LEAST ONE OF THE FOLLOWING
                    664:  *     CONDITIONS ARE TRUE:
                    665:  *
                    666:  *             (1) The pmap references the global kernel_lev1map.
                    667:  *
                    668:  *             (2) The pmap is not active on the current processor.
                    669:  */
                    670: #define        PMAP_INVALIDATE_ASN(pmap, cpu_id)                               \
                    671: do {                                                                   \
                    672:        (pmap)->pm_asn[(cpu_id)] = PMAP_ASN_RESERVED;                   \
                    673: } while (0)
                    674:
                    675: /*
                    676:  * PMAP_INVALIDATE_TLB:
                    677:  *
                    678:  *     Invalidate the TLB entry for the pmap/va pair.
                    679:  */
                    680: #define        PMAP_INVALIDATE_TLB(pmap, va, hadasm, isactive, cpu_id)         \
                    681: do {                                                                   \
                    682:        if ((hadasm) || (isactive)) {                                   \
                    683:                /*                                                      \
                    684:                 * Simply invalidating the TLB entry and I-cache        \
                    685:                 * works in this case.                                  \
                    686:                 */                                                     \
                    687:                ALPHA_TBIS((va));                                       \
                    688:        } else if ((pmap)->pm_asngen[(cpu_id)] ==                       \
                    689:            pmap_asn_generation[(cpu_id)]) {                            \
                    690:                /*                                                      \
                    691:                 * We can't directly invalidate the TLB entry           \
                    692:                 * in this case, so we have to force allocation         \
                    693:                 * of a new ASN the next time this pmap becomes         \
                    694:                 * active.                                              \
                    695:                 */                                                     \
                    696:                PMAP_INVALIDATE_ASN((pmap), (cpu_id));                  \
                    697:        }                                                               \
                    698:                /*                                                      \
                    699:                 * Nothing to do in this case; the next time the        \
                    700:                 * pmap becomes active on this processor, a new         \
                    701:                 * ASN will be allocated anyway.                        \
                    702:                 */                                                     \
                    703: } while (0)
                    704:
                    705: /*
                    706:  * PMAP_KERNEL_PTE:
                    707:  *
                    708:  *     Get a kernel PTE.
                    709:  *
                    710:  *     If debugging, do a table walk.  If not debugging, just use
                    711:  *     the Virtual Page Table, since all kernel page tables are
                    712:  *     pre-allocated and mapped in.
                    713:  */
                    714: #ifdef DEBUG
                    715: #define        PMAP_KERNEL_PTE(va)                                             \
                    716: ({                                                                     \
                    717:        pt_entry_t *l1pte_, *l2pte_;                                    \
                    718:                                                                        \
                    719:        l1pte_ = pmap_l1pte(pmap_kernel(), va);                         \
                    720:        if (pmap_pte_v(l1pte_) == 0) {                                  \
                    721:                printf("kernel level 1 PTE not valid, va 0x%lx "        \
                    722:                    "(line %d)\n", (va), __LINE__);                     \
                    723:                panic("PMAP_KERNEL_PTE");                               \
                    724:        }                                                               \
                    725:        l2pte_ = pmap_l2pte(pmap_kernel(), va, l1pte_);                 \
                    726:        if (pmap_pte_v(l2pte_) == 0) {                                  \
                    727:                printf("kernel level 2 PTE not valid, va 0x%lx "        \
                    728:                    "(line %d)\n", (va), __LINE__);                     \
                    729:                panic("PMAP_KERNEL_PTE");                               \
                    730:        }                                                               \
                    731:        pmap_l3pte(pmap_kernel(), va, l2pte_);                          \
                    732: })
                    733: #else
                    734: #define        PMAP_KERNEL_PTE(va)     (&VPT[VPT_INDEX((va))])
                    735: #endif
                    736:
                    737: /*
                    738:  * PMAP_SET_PTE:
                    739:  *
                    740:  *     Set a PTE to a specified value.
                    741:  */
                    742: #define        PMAP_SET_PTE(ptep, val) *(ptep) = (val)
                    743:
                    744: /*
                    745:  * PMAP_STAT_{INCR,DECR}:
                    746:  *
                    747:  *     Increment or decrement a pmap statistic.
                    748:  */
                    749: #define        PMAP_STAT_INCR(s, v)    atomic_add_ulong((unsigned long *)(&(s)), (v))
                    750: #define        PMAP_STAT_DECR(s, v)    atomic_sub_ulong((unsigned long *)(&(s)), (v))
                    751:
                    752: /*
                    753:  * pmap_bootstrap:
                    754:  *
                    755:  *     Bootstrap the system to run with virtual memory.
                    756:  *
                    757:  *     Note: no locking is necessary in this function.
                    758:  */
                    759: void
                    760: pmap_bootstrap(paddr_t ptaddr, u_int maxasn, u_long ncpuids)
                    761: {
                    762:        vsize_t lev2mapsize, lev3mapsize;
                    763:        pt_entry_t *lev2map, *lev3map;
                    764:        pt_entry_t pte;
                    765:        int i;
                    766:
                    767: #ifdef DEBUG
                    768:        if (pmapdebug & (PDB_FOLLOW|PDB_BOOTSTRAP))
                    769:                printf("pmap_bootstrap(0x%lx, %u)\n", ptaddr, maxasn);
                    770: #endif
                    771:
                    772:        /*
                    773:         * Compute the number of pages kmem_map will have.
                    774:         */
                    775:        kmeminit_nkmempages();
                    776:
                    777:        /*
                    778:         * Figure out how many PTE's are necessary to map the kernel.
                    779:         */
                    780:        lev3mapsize = (VM_PHYS_SIZE + 16 * NCARGS + PAGER_MAP_SIZE) /
                    781:            PAGE_SIZE + (maxproc * UPAGES) + nkmempages;
                    782:
                    783: #ifdef SYSVSHM
                    784:        lev3mapsize += shminfo.shmall;
                    785: #endif
                    786:        lev3mapsize = roundup(lev3mapsize, NPTEPG);
                    787:
                    788:        /*
                    789:         * Allocate a level 1 PTE table for the kernel.
                    790:         * This is always one page long.
                    791:         * IF THIS IS NOT A MULTIPLE OF PAGE_SIZE, ALL WILL GO TO HELL.
                    792:         */
                    793:        kernel_lev1map = (pt_entry_t *)
                    794:            pmap_steal_memory(sizeof(pt_entry_t) * NPTEPG, NULL, NULL);
                    795:
                    796:        /*
                    797:         * Allocate a level 2 PTE table for the kernel.
                    798:         * These must map all of the level3 PTEs.
                    799:         * IF THIS IS NOT A MULTIPLE OF PAGE_SIZE, ALL WILL GO TO HELL.
                    800:         */
                    801:        lev2mapsize = roundup(howmany(lev3mapsize, NPTEPG), NPTEPG);
                    802:        lev2map = (pt_entry_t *)
                    803:            pmap_steal_memory(sizeof(pt_entry_t) * lev2mapsize, NULL, NULL);
                    804:
                    805:        /*
                    806:         * Allocate a level 3 PTE table for the kernel.
                    807:         * Contains lev3mapsize PTEs.
                    808:         */
                    809:        lev3map = (pt_entry_t *)
                    810:            pmap_steal_memory(sizeof(pt_entry_t) * lev3mapsize, NULL, NULL);
                    811:
                    812:        /*
                    813:         * Allocate memory for the pv_heads.  (A few more of the latter
                    814:         * are allocated than are needed.)
                    815:         *
                    816:         * We could do this in pmap_init when we know the actual
                    817:         * managed page pool size, but its better to use kseg0
                    818:         * addresses rather than kernel virtual addresses mapped
                    819:         * through the TLB.
                    820:         */
                    821:        pv_table_npages = physmem;
                    822:        pv_table = (struct pv_head *)
                    823:            pmap_steal_memory(sizeof(struct pv_head) * pv_table_npages,
                    824:            NULL, NULL);
                    825:
                    826:        /*
                    827:         * ...and initialize the pv_entry list headers.
                    828:         */
                    829:        for (i = 0; i < pv_table_npages; i++) {
                    830:                LIST_INIT(&pv_table[i].pvh_list);
                    831:                simple_lock_init(&pv_table[i].pvh_slock);
                    832:        }
                    833:
                    834:        /*
                    835:         * Set up level 1 page table
                    836:         */
                    837:
                    838:        /* Map all of the level 2 pte pages */
                    839:        for (i = 0; i < howmany(lev2mapsize, NPTEPG); i++) {
                    840:                pte = (ALPHA_K0SEG_TO_PHYS(((vaddr_t)lev2map) +
                    841:                    (i*PAGE_SIZE)) >> PGSHIFT) << PG_SHIFT;
                    842:                pte |= PG_V | PG_ASM | PG_KRE | PG_KWE | PG_WIRED;
                    843:                kernel_lev1map[l1pte_index(VM_MIN_KERNEL_ADDRESS +
                    844:                    (i*PAGE_SIZE*NPTEPG*NPTEPG))] = pte;
                    845:        }
                    846:
                    847:        /* Map the virtual page table */
                    848:        pte = (ALPHA_K0SEG_TO_PHYS((vaddr_t)kernel_lev1map) >> PGSHIFT)
                    849:            << PG_SHIFT;
                    850:        pte |= PG_V | PG_KRE | PG_KWE; /* NOTE NO ASM */
                    851:        kernel_lev1map[l1pte_index(VPTBASE)] = pte;
                    852:        VPT = (pt_entry_t *)VPTBASE;
                    853:
                    854: #ifdef _PMAP_MAY_USE_PROM_CONSOLE
                    855:     {
                    856:        extern pt_entry_t prom_pte;                     /* XXX */
                    857:        extern int prom_mapped;                         /* XXX */
                    858:
                    859:        if (pmap_uses_prom_console()) {
                    860:                /*
                    861:                 * XXX Save old PTE so we can remap the PROM, if
                    862:                 * XXX necessary.
                    863:                 */
                    864:                prom_pte = *(pt_entry_t *)ptaddr & ~PG_ASM;
                    865:        }
                    866:        prom_mapped = 0;
                    867:
                    868:        /*
                    869:         * Actually, this code lies.  The prom is still mapped, and will
                    870:         * remain so until the context switch after alpha_init() returns.
                    871:         */
                    872:     }
                    873: #endif
                    874:
                    875:        /*
                    876:         * Set up level 2 page table.
                    877:         */
                    878:        /* Map all of the level 3 pte pages */
                    879:        for (i = 0; i < howmany(lev3mapsize, NPTEPG); i++) {
                    880:                pte = (ALPHA_K0SEG_TO_PHYS(((vaddr_t)lev3map) +
                    881:                    (i*PAGE_SIZE)) >> PGSHIFT) << PG_SHIFT;
                    882:                pte |= PG_V | PG_ASM | PG_KRE | PG_KWE | PG_WIRED;
                    883:                lev2map[l2pte_index(VM_MIN_KERNEL_ADDRESS+
                    884:                    (i*PAGE_SIZE*NPTEPG))] = pte;
                    885:        }
                    886:
                    887:        /* Initialize the pmap_growkernel_slock. */
                    888:        simple_lock_init(&pmap_growkernel_slock);
                    889:
                    890:        /*
                    891:         * Set up level three page table (lev3map)
                    892:         */
                    893:        /* Nothing to do; it's already zeroed */
                    894:
                    895:        /*
                    896:         * Initialize `FYI' variables.  Note we're relying on
                    897:         * the fact that BSEARCH sorts the vm_physmem[] array
                    898:         * for us.
                    899:         */
                    900:        avail_start = ptoa(vm_physmem[0].start);
                    901:        avail_end = ptoa(vm_physmem[vm_nphysseg - 1].end);
                    902:        virtual_avail = VM_MIN_KERNEL_ADDRESS;
                    903:        virtual_end = VM_MIN_KERNEL_ADDRESS + lev3mapsize * PAGE_SIZE;
                    904:
                    905: #if 0
                    906:        printf("avail_start = 0x%lx\n", avail_start);
                    907:        printf("avail_end = 0x%lx\n", avail_end);
                    908:        printf("virtual_avail = 0x%lx\n", virtual_avail);
                    909:        printf("virtual_end = 0x%lx\n", virtual_end);
                    910: #endif
                    911:
                    912:        /*
                    913:         * Initialize the pmap pools and list.
                    914:         */
                    915:        pmap_ncpuids = ncpuids;
                    916:        pool_init(&pmap_pmap_pool, sizeof(struct pmap), 0, 0, 0, "pmappl",
                    917:            &pool_allocator_nointr);
                    918:        pool_init(&pmap_l1pt_pool, PAGE_SIZE, 0, 0, 0, "l1ptpl",
                    919:            &pmap_l1pt_allocator);
                    920:        pool_cache_init(&pmap_l1pt_cache, &pmap_l1pt_pool, pmap_l1pt_ctor,
                    921:            NULL, NULL);
                    922:        pool_init(&pmap_asn_pool, pmap_ncpuids * sizeof(u_int), 0, 0, 0,
                    923:            "pmasnpl", &pool_allocator_nointr);
                    924:        pool_init(&pmap_asngen_pool, pmap_ncpuids * sizeof(u_long), 0, 0, 0,
                    925:            "pmasngenpl", &pool_allocator_nointr);
                    926:        pool_init(&pmap_pv_pool, sizeof(struct pv_entry), 0, 0, 0, "pvpl",
                    927:            &pmap_pv_allocator);
                    928:
                    929:        TAILQ_INIT(&pmap_all_pmaps);
                    930:
                    931:        /*
                    932:         * Initialize the ASN logic.
                    933:         */
                    934:        pmap_max_asn = maxasn;
                    935:        for (i = 0; i < ALPHA_MAXPROCS; i++) {
                    936:                pmap_next_asn[i] = 1;
                    937:                pmap_asn_generation[i] = 0;
                    938:        }
                    939:
                    940:        /*
                    941:         * Initialize the locks.
                    942:         */
                    943:        simple_lock_init(&pmap_all_pmaps_slock);
                    944:
                    945:        /*
                    946:         * Initialize kernel pmap.  Note that all kernel mappings
                    947:         * have PG_ASM set, so the ASN doesn't really matter for
                    948:         * the kernel pmap.  Also, since the kernel pmap always
                    949:         * references kernel_lev1map, it always has an invalid ASN
                    950:         * generation.
                    951:         */
                    952:        memset(pmap_kernel(), 0, sizeof(struct pmap));
                    953:        pmap_kernel()->pm_lev1map = kernel_lev1map;
                    954:        pmap_kernel()->pm_count = 1;
                    955:        pmap_kernel()->pm_asn = kernel_pmap_asn_store;
                    956:        pmap_kernel()->pm_asngen = kernel_pmap_asngen_store;
                    957:        for (i = 0; i < ALPHA_MAXPROCS; i++) {
                    958:                pmap_kernel()->pm_asn[i] = PMAP_ASN_RESERVED;
                    959:                pmap_kernel()->pm_asngen[i] = pmap_asn_generation[i];
                    960:        }
                    961:        simple_lock_init(&pmap_kernel()->pm_slock);
                    962:        TAILQ_INSERT_TAIL(&pmap_all_pmaps, pmap_kernel(), pm_list);
                    963:
                    964: #if defined(MULTIPROCESSOR)
                    965:        /*
                    966:         * Initialize the TLB shootdown queues.
                    967:         */
                    968:        pool_init(&pmap_tlb_shootdown_job_pool,
                    969:            sizeof(struct pmap_tlb_shootdown_job), 0, 0, 0, "pmaptlbpl",
                    970:            NULL);
                    971:        for (i = 0; i < ALPHA_MAXPROCS; i++) {
                    972:                TAILQ_INIT(&pmap_tlb_shootdown_q[i].pq_head);
                    973:                simple_lock_init(&pmap_tlb_shootdown_q[i].pq_slock);
                    974:        }
                    975: #endif
                    976:
                    977:        /*
                    978:         * Set up proc0's PCB such that the ptbr points to the right place
                    979:         * and has the kernel pmap's (really unused) ASN.
                    980:         */
                    981:        proc0.p_addr->u_pcb.pcb_hw.apcb_ptbr =
                    982:            ALPHA_K0SEG_TO_PHYS((vaddr_t)kernel_lev1map) >> PGSHIFT;
                    983:        proc0.p_addr->u_pcb.pcb_hw.apcb_asn =
                    984:            pmap_kernel()->pm_asn[cpu_number()];
                    985:
                    986:        /*
                    987:         * Mark the kernel pmap `active' on this processor.
                    988:         */
                    989:        atomic_setbits_ulong(&pmap_kernel()->pm_cpus,
                    990:            (1UL << cpu_number()));
                    991: }
                    992:
                    993: #ifdef _PMAP_MAY_USE_PROM_CONSOLE
                    994: int
                    995: pmap_uses_prom_console(void)
                    996: {
                    997:
                    998: #if defined(NEW_SCC_DRIVER)
                    999:        return (cputype == ST_DEC_21000);
                   1000: #else
                   1001:        return (cputype == ST_DEC_21000
                   1002:            || cputype == ST_DEC_3000_300
                   1003:            || cputype == ST_DEC_3000_500);
                   1004: #endif /* NEW_SCC_DRIVER */
                   1005: }
                   1006: #endif /* _PMAP_MAY_USE_PROM_CONSOLE */
                   1007:
                   1008: void
                   1009: pmap_virtual_space(vaddr_t *vstartp, vaddr_t *vendp)
                   1010: {
                   1011:        *vstartp = VM_MIN_KERNEL_ADDRESS;
                   1012:        *vendp = VM_MAX_KERNEL_ADDRESS;
                   1013: }
                   1014:
                   1015: /*
                   1016:  * pmap_steal_memory:          [ INTERFACE ]
                   1017:  *
                   1018:  *     Bootstrap memory allocator (alternative to vm_bootstrap_steal_memory()).
                   1019:  *     This function allows for early dynamic memory allocation until the
                   1020:  *     virtual memory system has been bootstrapped.  After that point, either
                   1021:  *     kmem_alloc or malloc should be used.  This function works by stealing
                   1022:  *     pages from the (to be) managed page pool, then implicitly mapping the
                   1023:  *     pages (by using their k0seg addresses) and zeroing them.
                   1024:  *
                   1025:  *     It may be used once the physical memory segments have been pre-loaded
                   1026:  *     into the vm_physmem[] array.  Early memory allocation MUST use this
                   1027:  *     interface!  This cannot be used after vm_page_startup(), and will
                   1028:  *     generate a panic if tried.
                   1029:  *
                   1030:  *     Note that this memory will never be freed, and in essence it is wired
                   1031:  *     down.
                   1032:  *
                   1033:  *     Note: no locking is necessary in this function.
                   1034:  */
                   1035: vaddr_t
                   1036: pmap_steal_memory(vsize_t size, vaddr_t *vstartp, vaddr_t *vendp)
                   1037: {
                   1038:        int bank, npgs, x;
                   1039:        vaddr_t va;
                   1040:        paddr_t pa;
                   1041:
                   1042:        size = round_page(size);
                   1043:        npgs = atop(size);
                   1044:
                   1045: #if 0
                   1046:        printf("PSM: size 0x%lx (npgs 0x%x)\n", size, npgs);
                   1047: #endif
                   1048:
                   1049:        for (bank = 0; bank < vm_nphysseg; bank++) {
                   1050:                if (uvm.page_init_done == TRUE)
                   1051:                        panic("pmap_steal_memory: called _after_ bootstrap");
                   1052:
                   1053:
                   1054: #if 0
                   1055:                printf("     bank %d: avail_start 0x%lx, start 0x%lx, "
                   1056:                    "avail_end 0x%lx\n", bank, vm_physmem[bank].avail_start,
                   1057:                    vm_physmem[bank].start, vm_physmem[bank].avail_end);
                   1058: #endif
                   1059:
                   1060:                if (vm_physmem[bank].avail_start != vm_physmem[bank].start ||
                   1061:                    vm_physmem[bank].avail_start >= vm_physmem[bank].avail_end)
                   1062:                        continue;
                   1063:
                   1064: #if 0
                   1065:                printf("             avail_end - avail_start = 0x%lx\n",
                   1066:                    vm_physmem[bank].avail_end - vm_physmem[bank].avail_start);
                   1067: #endif
                   1068:
                   1069:                if ((vm_physmem[bank].avail_end - vm_physmem[bank].avail_start)
                   1070:                    < npgs)
                   1071:                        continue;
                   1072:
                   1073:                /*
                   1074:                 * There are enough pages here; steal them!
                   1075:                 */
                   1076:                pa = ptoa(vm_physmem[bank].avail_start);
                   1077:                vm_physmem[bank].avail_start += npgs;
                   1078:                vm_physmem[bank].start += npgs;
                   1079:
                   1080:                /*
                   1081:                 * Have we used up this segment?
                   1082:                 */
                   1083:                if (vm_physmem[bank].avail_start == vm_physmem[bank].end) {
                   1084:                        if (vm_nphysseg == 1)
                   1085:                                panic("pmap_steal_memory: out of memory!");
                   1086:
                   1087:                        /* Remove this segment from the list. */
                   1088:                        vm_nphysseg--;
                   1089:                        for (x = bank; x < vm_nphysseg; x++) {
                   1090:                                /* structure copy */
                   1091:                                vm_physmem[x] = vm_physmem[x + 1];
                   1092:                        }
                   1093:                }
                   1094:
                   1095:                /*
                   1096:                 * Fill these in for the caller; we don't modify them,
                   1097:                 * but the upper layers still want to know.
                   1098:                 */
                   1099:                if (vstartp)
                   1100:                        *vstartp = round_page(virtual_avail);
                   1101:                if (vendp)
                   1102:                        *vendp = VM_MAX_KERNEL_ADDRESS;
                   1103:
                   1104:                va = ALPHA_PHYS_TO_K0SEG(pa);
                   1105:                memset((caddr_t)va, 0, size);
                   1106:                pmap_pages_stolen += npgs;
                   1107:                return (va);
                   1108:        }
                   1109:
                   1110:        /*
                   1111:         * If we got here, this was no memory left.
                   1112:         */
                   1113:        panic("pmap_steal_memory: no memory to steal");
                   1114: }
                   1115:
                   1116: /*
                   1117:  * pmap_init:                  [ INTERFACE ]
                   1118:  *
                   1119:  *     Initialize the pmap module.  Called by vm_init(), to initialize any
                   1120:  *     structures that the pmap system needs to map virtual memory.
                   1121:  *
                   1122:  *     Note: no locking is necessary in this function.
                   1123:  */
                   1124: void
                   1125: pmap_init(void)
                   1126: {
                   1127:        vsize_t         s;
                   1128:        int             bank;
                   1129:        struct pv_head  *pvh;
                   1130:
                   1131: #ifdef DEBUG
                   1132:         if (pmapdebug & PDB_FOLLOW)
                   1133:                 printf("pmap_init()\n");
                   1134: #endif
                   1135:
                   1136:        /* initialize protection array */
                   1137:        alpha_protection_init();
                   1138:
                   1139:        /*
                   1140:         * Memory for the pv heads has already been allocated.
                   1141:         * Initialize the physical memory segments.
                   1142:         */
                   1143:        pvh = pv_table;
                   1144:        for (bank = 0; bank < vm_nphysseg; bank++) {
                   1145:                s = vm_physmem[bank].end - vm_physmem[bank].start;
                   1146:                vm_physmem[bank].pmseg.pvhead = pvh;
                   1147:                pvh += s;
                   1148:        }
                   1149:
                   1150:        /*
                   1151:         * Set a low water mark on the pv_entry pool, so that we are
                   1152:         * more likely to have these around even in extreme memory
                   1153:         * starvation.
                   1154:         */
                   1155:        pool_setlowat(&pmap_pv_pool, pmap_pv_lowat);
                   1156:
                   1157:        /*
                   1158:         * Now it is safe to enable pv entry recording.
                   1159:         */
                   1160:        pmap_initialized = TRUE;
                   1161:
                   1162: #if 0
                   1163:        for (bank = 0; bank < vm_nphysseg; bank++) {
                   1164:                printf("bank %d\n", bank);
                   1165:                printf("\tstart = 0x%x\n", ptoa(vm_physmem[bank].start));
                   1166:                printf("\tend = 0x%x\n", ptoa(vm_physmem[bank].end));
                   1167:                printf("\tavail_start = 0x%x\n",
                   1168:                    ptoa(vm_physmem[bank].avail_start));
                   1169:                printf("\tavail_end = 0x%x\n",
                   1170:                    ptoa(vm_physmem[bank].avail_end));
                   1171:        }
                   1172: #endif
                   1173: }
                   1174:
                   1175: /*
                   1176:  * pmap_create:                        [ INTERFACE ]
                   1177:  *
                   1178:  *     Create and return a physical map.
                   1179:  *
                   1180:  *     Note: no locking is necessary in this function.
                   1181:  */
                   1182: pmap_t
                   1183: pmap_create(void)
                   1184: {
                   1185:        pmap_t pmap;
                   1186:        int i;
                   1187:
                   1188: #ifdef DEBUG
                   1189:        if (pmapdebug & (PDB_FOLLOW|PDB_CREATE))
                   1190:                printf("pmap_create()\n");
                   1191: #endif
                   1192:
                   1193:        pmap = pool_get(&pmap_pmap_pool, PR_WAITOK);
                   1194:        memset(pmap, 0, sizeof(*pmap));
                   1195:
                   1196:        pmap->pm_asn = pool_get(&pmap_asn_pool, PR_WAITOK);
                   1197:        pmap->pm_asngen = pool_get(&pmap_asngen_pool, PR_WAITOK);
                   1198:
                   1199:        /*
                   1200:         * Defer allocation of a new level 1 page table until
                   1201:         * the first new mapping is entered; just take a reference
                   1202:         * to the kernel kernel_lev1map.
                   1203:         */
                   1204:        pmap->pm_lev1map = kernel_lev1map;
                   1205:
                   1206:        pmap->pm_count = 1;
                   1207:        for (i = 0; i < pmap_ncpuids; i++) {
                   1208:                pmap->pm_asn[i] = PMAP_ASN_RESERVED;
                   1209:                /* XXX Locking? */
                   1210:                pmap->pm_asngen[i] = pmap_asn_generation[i];
                   1211:        }
                   1212:        simple_lock_init(&pmap->pm_slock);
                   1213:
                   1214:        simple_lock(&pmap_all_pmaps_slock);
                   1215:        TAILQ_INSERT_TAIL(&pmap_all_pmaps, pmap, pm_list);
                   1216:        simple_unlock(&pmap_all_pmaps_slock);
                   1217:
                   1218:        return (pmap);
                   1219: }
                   1220:
                   1221: /*
                   1222:  * pmap_destroy:               [ INTERFACE ]
                   1223:  *
                   1224:  *     Drop the reference count on the specified pmap, releasing
                   1225:  *     all resources if the reference count drops to zero.
                   1226:  */
                   1227: void
                   1228: pmap_destroy(pmap_t pmap)
                   1229: {
                   1230:        int refs;
                   1231:
                   1232: #ifdef DEBUG
                   1233:        if (pmapdebug & PDB_FOLLOW)
                   1234:                printf("pmap_destroy(%p)\n", pmap);
                   1235: #endif
                   1236:        if (pmap == NULL)
                   1237:                return;
                   1238:
                   1239:        PMAP_LOCK(pmap);
                   1240:        refs = --pmap->pm_count;
                   1241:        PMAP_UNLOCK(pmap);
                   1242:
                   1243:        if (refs > 0)
                   1244:                return;
                   1245:
                   1246:        /*
                   1247:         * Remove it from the global list of all pmaps.
                   1248:         */
                   1249:        simple_lock(&pmap_all_pmaps_slock);
                   1250:        TAILQ_REMOVE(&pmap_all_pmaps, pmap, pm_list);
                   1251:        simple_unlock(&pmap_all_pmaps_slock);
                   1252:
                   1253: #ifdef DIAGNOSTIC
                   1254:        /*
                   1255:         * Since the pmap is supposed to contain no valid
                   1256:         * mappings at this point, this should never happen.
                   1257:         */
                   1258:        if (pmap->pm_lev1map != kernel_lev1map) {
                   1259:                printf("pmap_release: pmap still contains valid mappings!\n");
                   1260:                if (pmap->pm_nlev2)
                   1261:                        printf("pmap_release: %ld level 2 tables left\n",
                   1262:                            pmap->pm_nlev2);
                   1263:                if (pmap->pm_nlev3)
                   1264:                        printf("pmap_release: %ld level 3 tables left\n",
                   1265:                            pmap->pm_nlev3);
                   1266:                pmap_remove(pmap, VM_MIN_ADDRESS, VM_MAX_ADDRESS);
                   1267:                pmap_update(pmap);
                   1268:                if (pmap->pm_lev1map != kernel_lev1map)
                   1269:                        panic("pmap_release: pmap_remove() didn't");
                   1270:        }
                   1271: #endif
                   1272:
                   1273:        pool_put(&pmap_asn_pool, pmap->pm_asn);
                   1274:        pool_put(&pmap_asngen_pool, pmap->pm_asngen);
                   1275:        pool_put(&pmap_pmap_pool, pmap);
                   1276: }
                   1277:
                   1278: /*
                   1279:  * pmap_reference:             [ INTERFACE ]
                   1280:  *
                   1281:  *     Add a reference to the specified pmap.
                   1282:  */
                   1283: void
                   1284: pmap_reference(pmap_t pmap)
                   1285: {
                   1286:
                   1287: #ifdef DEBUG
                   1288:        if (pmapdebug & PDB_FOLLOW)
                   1289:                printf("pmap_reference(%p)\n", pmap);
                   1290: #endif
                   1291:        if (pmap != NULL) {
                   1292:                PMAP_LOCK(pmap);
                   1293:                pmap->pm_count++;
                   1294:                PMAP_UNLOCK(pmap);
                   1295:        }
                   1296: }
                   1297:
                   1298: /*
                   1299:  * pmap_remove:                        [ INTERFACE ]
                   1300:  *
                   1301:  *     Remove the given range of addresses from the specified map.
                   1302:  *
                   1303:  *     It is assumed that the start and end are properly
                   1304:  *     rounded to the page size.
                   1305:  */
                   1306: void
                   1307: pmap_remove(pmap_t pmap, vaddr_t sva, vaddr_t eva)
                   1308: {
                   1309:
                   1310: #ifdef DEBUG
                   1311:        if (pmapdebug & (PDB_FOLLOW|PDB_REMOVE|PDB_PROTECT))
                   1312:                printf("pmap_remove(%p, %lx, %lx)\n", pmap, sva, eva);
                   1313: #endif
                   1314:
                   1315:        pmap_do_remove(pmap, sva, eva, TRUE);
                   1316: }
                   1317:
                   1318: /*
                   1319:  * pmap_do_remove:
                   1320:  *
                   1321:  *     This actually removes the range of addresses from the
                   1322:  *     specified map.  It is used by pmap_collect() (does not
                   1323:  *     want to remove wired mappings) and pmap_remove() (does
                   1324:  *     want to remove wired mappings).
                   1325:  */
                   1326: void
                   1327: pmap_do_remove(pmap_t pmap, vaddr_t sva, vaddr_t eva, boolean_t dowired)
                   1328: {
                   1329:        pt_entry_t *l1pte, *l2pte, *l3pte;
                   1330:        pt_entry_t *saved_l1pte, *saved_l2pte, *saved_l3pte;
                   1331:        vaddr_t l1eva, l2eva, vptva;
                   1332:        boolean_t needisync = FALSE;
                   1333:        cpuid_t cpu_id = cpu_number();
                   1334:
                   1335: #ifdef DEBUG
                   1336:        if (pmapdebug & (PDB_FOLLOW|PDB_REMOVE|PDB_PROTECT))
                   1337:                printf("pmap_remove(%p, %lx, %lx)\n", pmap, sva, eva);
                   1338: #endif
                   1339:
                   1340:        if (pmap == NULL)
                   1341:                return;
                   1342:
                   1343:        /*
                   1344:         * If this is the kernel pmap, we can use a faster method
                   1345:         * for accessing the PTEs (since the PT pages are always
                   1346:         * resident).
                   1347:         *
                   1348:         * Note that this routine should NEVER be called from an
                   1349:         * interrupt context; pmap_kremove() is used for that.
                   1350:         */
                   1351:        if (pmap == pmap_kernel()) {
                   1352:                PMAP_MAP_TO_HEAD_LOCK();
                   1353:                PMAP_LOCK(pmap);
                   1354:
                   1355:                KASSERT(dowired == TRUE);
                   1356:
                   1357:                while (sva < eva) {
                   1358:                        l3pte = PMAP_KERNEL_PTE(sva);
                   1359:                        if (pmap_pte_v(l3pte)) {
                   1360: #ifdef DIAGNOSTIC
                   1361:                                if (PAGE_IS_MANAGED(pmap_pte_pa(l3pte)) &&
                   1362:                                    pmap_pte_pv(l3pte) == 0)
                   1363:                                        panic("pmap_remove: managed page "
                   1364:                                            "without PG_PVLIST for 0x%lx",
                   1365:                                            sva);
                   1366: #endif
                   1367:                                needisync |= pmap_remove_mapping(pmap, sva,
                   1368:                                    l3pte, TRUE, cpu_id, NULL);
                   1369:                        }
                   1370:                        sva += PAGE_SIZE;
                   1371:                }
                   1372:
                   1373:                PMAP_UNLOCK(pmap);
                   1374:                PMAP_MAP_TO_HEAD_UNLOCK();
                   1375:
                   1376:                if (needisync)
                   1377:                        PMAP_SYNC_ISTREAM_KERNEL();
                   1378:                return;
                   1379:        }
                   1380:
                   1381: #ifdef DIAGNOSTIC
                   1382:        if (sva > VM_MAXUSER_ADDRESS || eva > VM_MAXUSER_ADDRESS)
                   1383:                panic("pmap_remove: (0x%lx - 0x%lx) user pmap, kernel "
                   1384:                    "address range", sva, eva);
                   1385: #endif
                   1386:
                   1387:        PMAP_MAP_TO_HEAD_LOCK();
                   1388:        PMAP_LOCK(pmap);
                   1389:
                   1390:        /*
                   1391:         * If we're already referencing the kernel_lev1map, there
                   1392:         * is no work for us to do.
                   1393:         */
                   1394:        if (pmap->pm_lev1map == kernel_lev1map)
                   1395:                goto out;
                   1396:
                   1397:        saved_l1pte = l1pte = pmap_l1pte(pmap, sva);
                   1398:
                   1399:        /*
                   1400:         * Add a reference to the L1 table to it won't get
                   1401:         * removed from under us.
                   1402:         */
                   1403:        pmap_physpage_addref(saved_l1pte);
                   1404:
                   1405:        for (; sva < eva; sva = l1eva, l1pte++) {
                   1406:                l1eva = alpha_trunc_l1seg(sva) + ALPHA_L1SEG_SIZE;
                   1407:                if (pmap_pte_v(l1pte)) {
                   1408:                        saved_l2pte = l2pte = pmap_l2pte(pmap, sva, l1pte);
                   1409:
                   1410:                        /*
                   1411:                         * Add a reference to the L2 table so it won't
                   1412:                         * get removed from under us.
                   1413:                         */
                   1414:                        pmap_physpage_addref(saved_l2pte);
                   1415:
                   1416:                        for (; sva < l1eva && sva < eva; sva = l2eva, l2pte++) {
                   1417:                                l2eva =
                   1418:                                    alpha_trunc_l2seg(sva) + ALPHA_L2SEG_SIZE;
                   1419:                                if (pmap_pte_v(l2pte)) {
                   1420:                                        saved_l3pte = l3pte =
                   1421:                                            pmap_l3pte(pmap, sva, l2pte);
                   1422:
                   1423:                                        /*
                   1424:                                         * Add a reference to the L3 table so
                   1425:                                         * it won't get removed from under us.
                   1426:                                         */
                   1427:                                        pmap_physpage_addref(saved_l3pte);
                   1428:
                   1429:                                        /*
                   1430:                                         * Remember this sva; if the L3 table
                   1431:                                         * gets removed, we need to invalidate
                   1432:                                         * the VPT TLB entry for it.
                   1433:                                         */
                   1434:                                        vptva = sva;
                   1435:
                   1436:                                        for (; sva < l2eva && sva < eva;
                   1437:                                             sva += PAGE_SIZE, l3pte++) {
                   1438:                                                if (pmap_pte_v(l3pte) &&
                   1439:                                                    (dowired == TRUE ||
                   1440:                                                     pmap_pte_w(l3pte) == 0)) {
                   1441:                                                        needisync |=
                   1442:                                                            pmap_remove_mapping(
                   1443:                                                                pmap, sva,
                   1444:                                                                l3pte, TRUE,
                   1445:                                                                cpu_id, NULL);
                   1446:                                                }
                   1447:                                        }
                   1448:
                   1449:                                        /*
                   1450:                                         * Remove the reference to the L3
                   1451:                                         * table that we added above.  This
                   1452:                                         * may free the L3 table.
                   1453:                                         */
                   1454:                                        pmap_l3pt_delref(pmap, vptva,
                   1455:                                            saved_l3pte, cpu_id, NULL);
                   1456:                                }
                   1457:                        }
                   1458:
                   1459:                        /*
                   1460:                         * Remove the reference to the L2 table that we
                   1461:                         * added above.  This may free the L2 table.
                   1462:                         */
                   1463:                        pmap_l2pt_delref(pmap, l1pte, saved_l2pte, cpu_id);
                   1464:                }
                   1465:        }
                   1466:
                   1467:        /*
                   1468:         * Remove the reference to the L1 table that we added above.
                   1469:         * This may free the L1 table.
                   1470:         */
                   1471:        pmap_l1pt_delref(pmap, saved_l1pte, cpu_id);
                   1472:
                   1473:        if (needisync)
                   1474:                PMAP_SYNC_ISTREAM_USER(pmap);
                   1475:
                   1476:  out:
                   1477:        PMAP_UNLOCK(pmap);
                   1478:        PMAP_MAP_TO_HEAD_UNLOCK();
                   1479: }
                   1480:
                   1481: /*
                   1482:  * pmap_page_protect:          [ INTERFACE ]
                   1483:  *
                   1484:  *     Lower the permission for all mappings to a given page to
                   1485:  *     the permissions specified.
                   1486:  */
                   1487: void
                   1488: pmap_page_protect(struct vm_page *pg, vm_prot_t prot)
                   1489: {
                   1490:        pmap_t pmap;
                   1491:        struct pv_head *pvh;
                   1492:        pv_entry_t pv, nextpv;
                   1493:        boolean_t needkisync = FALSE;
                   1494:        cpuid_t cpu_id = cpu_number();
                   1495:        paddr_t pa = VM_PAGE_TO_PHYS(pg);
                   1496:
                   1497: #ifdef DEBUG
                   1498:        if ((pmapdebug & (PDB_FOLLOW|PDB_PROTECT)) ||
                   1499:            (prot == VM_PROT_NONE && (pmapdebug & PDB_REMOVE)))
                   1500:                printf("pmap_page_protect(%p, %x)\n", pg, prot);
                   1501: #endif
                   1502:
                   1503:        switch (prot) {
                   1504:        case VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE:
                   1505:        case VM_PROT_READ|VM_PROT_WRITE:
                   1506:                return;
                   1507:        /* copy_on_write */
                   1508:        case VM_PROT_READ|VM_PROT_EXECUTE:
                   1509:        case VM_PROT_READ:
                   1510:                pvh = pa_to_pvh(pa);
                   1511:                PMAP_HEAD_TO_MAP_LOCK();
                   1512:                simple_lock(&pvh->pvh_slock);
                   1513: /* XXX */      pmap_changebit(pa, 0, ~(PG_KWE | PG_UWE), cpu_id);
                   1514:                simple_unlock(&pvh->pvh_slock);
                   1515:                PMAP_HEAD_TO_MAP_UNLOCK();
                   1516:                return;
                   1517:        /* remove_all */
                   1518:        default:
                   1519:                break;
                   1520:        }
                   1521:
                   1522:        pvh = pa_to_pvh(pa);
                   1523:        PMAP_HEAD_TO_MAP_LOCK();
                   1524:        simple_lock(&pvh->pvh_slock);
                   1525:        for (pv = LIST_FIRST(&pvh->pvh_list); pv != NULL; pv = nextpv) {
                   1526:                nextpv = LIST_NEXT(pv, pv_list);
                   1527:                pmap = pv->pv_pmap;
                   1528:
                   1529:                PMAP_LOCK(pmap);
                   1530: #ifdef DEBUG
                   1531:                if (pmap_pte_v(pmap_l2pte(pv->pv_pmap, pv->pv_va, NULL)) == 0 ||
                   1532:                    pmap_pte_pa(pv->pv_pte) != pa)
                   1533:                        panic("pmap_page_protect: bad mapping");
                   1534: #endif
                   1535:                if (pmap_pte_w(pv->pv_pte) == 0) {
                   1536:                        if (pmap_remove_mapping(pmap, pv->pv_va, pv->pv_pte,
                   1537:                            FALSE, cpu_id, NULL) == TRUE) {
                   1538:                                if (pmap == pmap_kernel())
                   1539:                                        needkisync |= TRUE;
                   1540:                                else
                   1541:                                        PMAP_SYNC_ISTREAM_USER(pmap);
                   1542:                        }
                   1543:                }
                   1544: #ifdef DEBUG
                   1545:                else {
                   1546:                        if (pmapdebug & PDB_PARANOIA) {
                   1547:                                printf("%s wired mapping for %lx not removed\n",
                   1548:                                       "pmap_page_protect:", pa);
                   1549:                                printf("vm wire count %d\n",
                   1550:                                        PHYS_TO_VM_PAGE(pa)->wire_count);
                   1551:                        }
                   1552:                }
                   1553: #endif
                   1554:                PMAP_UNLOCK(pmap);
                   1555:        }
                   1556:
                   1557:        if (needkisync)
                   1558:                PMAP_SYNC_ISTREAM_KERNEL();
                   1559:
                   1560:        simple_unlock(&pvh->pvh_slock);
                   1561:        PMAP_HEAD_TO_MAP_UNLOCK();
                   1562: }
                   1563:
                   1564: /*
                   1565:  * pmap_protect:               [ INTERFACE ]
                   1566:  *
                   1567:  *     Set the physical protection on the specified range of this map
                   1568:  *     as requested.
                   1569:  */
                   1570: void
                   1571: pmap_protect(pmap_t pmap, vaddr_t sva, vaddr_t eva, vm_prot_t prot)
                   1572: {
                   1573:        pt_entry_t *l1pte, *l2pte, *l3pte, bits;
                   1574:        boolean_t isactive;
                   1575:        boolean_t hadasm;
                   1576:        vaddr_t l1eva, l2eva;
                   1577:        cpuid_t cpu_id = cpu_number();
                   1578:
                   1579: #ifdef DEBUG
                   1580:        if (pmapdebug & (PDB_FOLLOW|PDB_PROTECT))
                   1581:                printf("pmap_protect(%p, %lx, %lx, %x)\n",
                   1582:                    pmap, sva, eva, prot);
                   1583: #endif
                   1584:
                   1585:        if (pmap == NULL)
                   1586:                return;
                   1587:
                   1588:        if ((prot & VM_PROT_READ) == VM_PROT_NONE) {
                   1589:                pmap_remove(pmap, sva, eva);
                   1590:                return;
                   1591:        }
                   1592:
                   1593:        if (prot & VM_PROT_WRITE)
                   1594:                return;
                   1595:
                   1596:        PMAP_LOCK(pmap);
                   1597:
                   1598:        bits = pte_prot(pmap, prot);
                   1599:        if (!pmap_pte_exec(&bits))
                   1600:                bits |= PG_FOE;
                   1601:        isactive = PMAP_ISACTIVE(pmap, cpu_id);
                   1602:
                   1603:        l1pte = pmap_l1pte(pmap, sva);
                   1604:        for (; sva < eva; sva = l1eva, l1pte++) {
                   1605:                l1eva = alpha_trunc_l1seg(sva) + ALPHA_L1SEG_SIZE;
                   1606:                if (pmap_pte_v(l1pte)) {
                   1607:                        l2pte = pmap_l2pte(pmap, sva, l1pte);
                   1608:                        for (; sva < l1eva && sva < eva; sva = l2eva, l2pte++) {
                   1609:                                l2eva =
                   1610:                                    alpha_trunc_l2seg(sva) + ALPHA_L2SEG_SIZE;
                   1611:                                if (pmap_pte_v(l2pte)) {
                   1612:                                        l3pte = pmap_l3pte(pmap, sva, l2pte);
                   1613:                                        for (; sva < l2eva && sva < eva;
                   1614:                                             sva += PAGE_SIZE, l3pte++) {
                   1615:                                                if (pmap_pte_v(l3pte) &&
                   1616:                                                    pmap_pte_prot_chg(l3pte,
                   1617:                                                    bits)) {
                   1618:                                                        hadasm =
                   1619:                                                           (pmap_pte_asm(l3pte)
                   1620:                                                            != 0);
                   1621:                                                        pmap_pte_set_prot(l3pte,
                   1622:                                                           bits);
                   1623:                                                        PMAP_INVALIDATE_TLB(
                   1624:                                                           pmap, sva, hadasm,
                   1625:                                                           isactive, cpu_id);
                   1626:                                                        PMAP_TLB_SHOOTDOWN(
                   1627:                                                           pmap, sva,
                   1628:                                                           hadasm ? PG_ASM : 0);
                   1629:                                                }
                   1630:                                        }
                   1631:                                }
                   1632:                        }
                   1633:                }
                   1634:        }
                   1635:
                   1636:        if (prot & VM_PROT_EXECUTE)
                   1637:                PMAP_SYNC_ISTREAM(pmap);
                   1638:
                   1639:        PMAP_UNLOCK(pmap);
                   1640: }
                   1641:
                   1642: /*
                   1643:  * pmap_enter:                 [ INTERFACE ]
                   1644:  *
                   1645:  *     Insert the given physical page (p) at
                   1646:  *     the specified virtual address (v) in the
                   1647:  *     target physical map with the protection requested.
                   1648:  *
                   1649:  *     If specified, the page will be wired down, meaning
                   1650:  *     that the related pte can not be reclaimed.
                   1651:  *
                   1652:  *     Note:  This is the only routine which MAY NOT lazy-evaluate
                   1653:  *     or lose information.  That is, this routine must actually
                   1654:  *     insert this page into the given map NOW.
                   1655:  */
                   1656: int
                   1657: pmap_enter(pmap_t pmap, vaddr_t va, paddr_t pa, vm_prot_t prot, int flags)
                   1658: {
                   1659:        boolean_t managed;
                   1660:        pt_entry_t *pte, npte, opte;
                   1661:        paddr_t opa;
                   1662:        boolean_t tflush = TRUE;
                   1663:        boolean_t hadasm = FALSE;       /* XXX gcc -Wuninitialized */
                   1664:        boolean_t needisync = FALSE;
                   1665:        boolean_t setisync = FALSE;
                   1666:        boolean_t isactive;
                   1667:        boolean_t wired;
                   1668:        cpuid_t cpu_id = cpu_number();
                   1669:        int error = 0;
                   1670:
                   1671: #ifdef DEBUG
                   1672:        if (pmapdebug & (PDB_FOLLOW|PDB_ENTER))
                   1673:                printf("pmap_enter(%p, %lx, %lx, %x, %x)\n",
                   1674:                       pmap, va, pa, prot, flags);
                   1675: #endif
                   1676:        managed = PAGE_IS_MANAGED(pa);
                   1677:        isactive = PMAP_ISACTIVE(pmap, cpu_id);
                   1678:        wired = (flags & PMAP_WIRED) != 0;
                   1679:
                   1680:        /*
                   1681:         * Determine what we need to do about the I-stream.  If
                   1682:         * VM_PROT_EXECUTE is set, we mark a user pmap as needing
                   1683:         * an I-sync on the way back out to userspace.  We always
                   1684:         * need an immediate I-sync for the kernel pmap.
                   1685:         */
                   1686:        if (prot & VM_PROT_EXECUTE) {
                   1687:                if (pmap == pmap_kernel())
                   1688:                        needisync = TRUE;
                   1689:                else {
                   1690:                        setisync = TRUE;
                   1691:                        needisync = (pmap->pm_cpus != 0);
                   1692:                }
                   1693:        }
                   1694:
                   1695:        PMAP_MAP_TO_HEAD_LOCK();
                   1696:        PMAP_LOCK(pmap);
                   1697:
                   1698:        if (pmap == pmap_kernel()) {
                   1699: #ifdef DIAGNOSTIC
                   1700:                /*
                   1701:                 * Sanity check the virtual address.
                   1702:                 */
                   1703:                if (va < VM_MIN_KERNEL_ADDRESS)
                   1704:                        panic("pmap_enter: kernel pmap, invalid va 0x%lx", va);
                   1705: #endif
                   1706:                pte = PMAP_KERNEL_PTE(va);
                   1707:        } else {
                   1708:                pt_entry_t *l1pte, *l2pte;
                   1709:
                   1710: #ifdef DIAGNOSTIC
                   1711:                /*
                   1712:                 * Sanity check the virtual address.
                   1713:                 */
                   1714:                if (va >= VM_MAXUSER_ADDRESS)
                   1715:                        panic("pmap_enter: user pmap, invalid va 0x%lx", va);
                   1716: #endif
                   1717:
                   1718:                /*
                   1719:                 * If we're still referencing the kernel kernel_lev1map,
                   1720:                 * create a new level 1 page table.  A reference will be
                   1721:                 * added to the level 1 table when the level 2 table is
                   1722:                 * created.
                   1723:                 */
                   1724:                if (pmap->pm_lev1map == kernel_lev1map) {
                   1725:                        error = pmap_lev1map_create(pmap, cpu_id);
                   1726:                        if (error) {
                   1727:                                if (flags & PMAP_CANFAIL)
                   1728:                                        goto out;
                   1729:                                panic("pmap_enter: unable to create lev1map");
                   1730:                        }
                   1731:                }
                   1732:
                   1733:                /*
                   1734:                 * Check to see if the level 1 PTE is valid, and
                   1735:                 * allocate a new level 2 page table page if it's not.
                   1736:                 * A reference will be added to the level 2 table when
                   1737:                 * the level 3 table is created.
                   1738:                 */
                   1739:                l1pte = pmap_l1pte(pmap, va);
                   1740:                if (pmap_pte_v(l1pte) == 0) {
                   1741:                        pmap_physpage_addref(l1pte);
                   1742:                        error = pmap_ptpage_alloc(pmap, l1pte, PGU_L2PT);
                   1743:                        if (error) {
                   1744:                                pmap_l1pt_delref(pmap, l1pte, cpu_id);
                   1745:                                if (flags & PMAP_CANFAIL)
                   1746:                                        goto out;
                   1747:                                panic("pmap_enter: unable to create L2 PT "
                   1748:                                    "page");
                   1749:                        }
                   1750:                        pmap->pm_nlev2++;
                   1751: #ifdef DEBUG
                   1752:                        if (pmapdebug & PDB_PTPAGE)
                   1753:                                printf("pmap_enter: new level 2 table at "
                   1754:                                    "0x%lx\n", pmap_pte_pa(l1pte));
                   1755: #endif
                   1756:                }
                   1757:
                   1758:                /*
                   1759:                 * Check to see if the level 2 PTE is valid, and
                   1760:                 * allocate a new level 3 page table page if it's not.
                   1761:                 * A reference will be added to the level 3 table when
                   1762:                 * the mapping is validated.
                   1763:                 */
                   1764:                l2pte = pmap_l2pte(pmap, va, l1pte);
                   1765:                if (pmap_pte_v(l2pte) == 0) {
                   1766:                        pmap_physpage_addref(l2pte);
                   1767:                        error = pmap_ptpage_alloc(pmap, l2pte, PGU_L3PT);
                   1768:                        if (error) {
                   1769:                                pmap_l2pt_delref(pmap, l1pte, l2pte, cpu_id);
                   1770:                                if (flags & PMAP_CANFAIL)
                   1771:                                        goto out;
                   1772:                                panic("pmap_enter: unable to create L3 PT "
                   1773:                                    "page");
                   1774:                        }
                   1775:                        pmap->pm_nlev3++;
                   1776: #ifdef DEBUG
                   1777:                        if (pmapdebug & PDB_PTPAGE)
                   1778:                                printf("pmap_enter: new level 3 table at "
                   1779:                                    "0x%lx\n", pmap_pte_pa(l2pte));
                   1780: #endif
                   1781:                }
                   1782:
                   1783:                /*
                   1784:                 * Get the PTE that will map the page.
                   1785:                 */
                   1786:                pte = pmap_l3pte(pmap, va, l2pte);
                   1787:        }
                   1788:
                   1789:        /* Remember all of the old PTE; used for TBI check later. */
                   1790:        opte = *pte;
                   1791:
                   1792:        /*
                   1793:         * Check to see if the old mapping is valid.  If not, validate the
                   1794:         * new one immediately.
                   1795:         */
                   1796:        if (pmap_pte_v(pte) == 0) {
                   1797:                /*
                   1798:                 * No need to invalidate the TLB in this case; an invalid
                   1799:                 * mapping won't be in the TLB, and a previously valid
                   1800:                 * mapping would have been flushed when it was invalidated.
                   1801:                 */
                   1802:                tflush = FALSE;
                   1803:
                   1804:                /*
                   1805:                 * No need to synchronize the I-stream, either, for basically
                   1806:                 * the same reason.
                   1807:                 */
                   1808:                setisync = needisync = FALSE;
                   1809:
                   1810:                if (pmap != pmap_kernel()) {
                   1811:                        /*
                   1812:                         * New mappings gain a reference on the level 3
                   1813:                         * table.
                   1814:                         */
                   1815:                        pmap_physpage_addref(pte);
                   1816:                }
                   1817:                goto validate_enterpv;
                   1818:        }
                   1819:
                   1820:        opa = pmap_pte_pa(pte);
                   1821:        hadasm = (pmap_pte_asm(pte) != 0);
                   1822:
                   1823:        if (opa == pa) {
                   1824:                /*
                   1825:                 * Mapping has not changed; must be a protection or
                   1826:                 * wiring change.
                   1827:                 */
                   1828:                if (pmap_pte_w_chg(pte, wired ? PG_WIRED : 0)) {
                   1829: #ifdef DEBUG
                   1830:                        if (pmapdebug & PDB_ENTER)
                   1831:                                printf("pmap_enter: wiring change -> %d\n",
                   1832:                                    wired);
                   1833: #endif
                   1834:                        /*
                   1835:                         * Adjust the wiring count.
                   1836:                         */
                   1837:                        if (wired)
                   1838:                                PMAP_STAT_INCR(pmap->pm_stats.wired_count, 1);
                   1839:                        else
                   1840:                                PMAP_STAT_DECR(pmap->pm_stats.wired_count, 1);
                   1841:                }
                   1842:
                   1843:                /*
                   1844:                 * Set the PTE.
                   1845:                 */
                   1846:                goto validate;
                   1847:        }
                   1848:
                   1849:        /*
                   1850:         * The mapping has changed.  We need to invalidate the
                   1851:         * old mapping before creating the new one.
                   1852:         */
                   1853: #ifdef DEBUG
                   1854:        if (pmapdebug & PDB_ENTER)
                   1855:                printf("pmap_enter: removing old mapping 0x%lx\n", va);
                   1856: #endif
                   1857:        if (pmap != pmap_kernel()) {
                   1858:                /*
                   1859:                 * Gain an extra reference on the level 3 table.
                   1860:                 * pmap_remove_mapping() will delete a reference,
                   1861:                 * and we don't want the table to be erroneously
                   1862:                 * freed.
                   1863:                 */
                   1864:                pmap_physpage_addref(pte);
                   1865:        }
                   1866:        needisync |= pmap_remove_mapping(pmap, va, pte, TRUE, cpu_id, NULL);
                   1867:
                   1868:  validate_enterpv:
                   1869:        /*
                   1870:         * Enter the mapping into the pv_table if appropriate.
                   1871:         */
                   1872:        if (managed) {
                   1873:                error = pmap_pv_enter(pmap, pa, va, pte, TRUE);
                   1874:                if (error) {
                   1875:                        pmap_l3pt_delref(pmap, va, pte, cpu_id, NULL);
                   1876:                        if (flags & PMAP_CANFAIL)
                   1877:                                goto out;
                   1878:                        panic("pmap_enter: unable to enter mapping in PV "
                   1879:                            "table");
                   1880:                }
                   1881:        }
                   1882:
                   1883:        /*
                   1884:         * Increment counters.
                   1885:         */
                   1886:        PMAP_STAT_INCR(pmap->pm_stats.resident_count, 1);
                   1887:        if (wired)
                   1888:                PMAP_STAT_INCR(pmap->pm_stats.wired_count, 1);
                   1889:
                   1890:  validate:
                   1891:        /*
                   1892:         * Build the new PTE.
                   1893:         */
                   1894:        npte = ((pa >> PGSHIFT) << PG_SHIFT) | pte_prot(pmap, prot) | PG_V;
                   1895:        if (managed) {
                   1896:                struct pv_head *pvh = pa_to_pvh(pa);
                   1897:                int attrs;
                   1898:
                   1899: #ifdef DIAGNOSTIC
                   1900:                if ((flags & VM_PROT_ALL) & ~prot)
                   1901:                        panic("pmap_enter: access type exceeds prot");
                   1902: #endif
                   1903:                simple_lock(&pvh->pvh_slock);
                   1904:                if (flags & VM_PROT_WRITE)
                   1905:                        pvh->pvh_attrs |= (PGA_REFERENCED|PGA_MODIFIED);
                   1906:                else if (flags & VM_PROT_ALL)
                   1907:                        pvh->pvh_attrs |= PGA_REFERENCED;
                   1908:                attrs = pvh->pvh_attrs;
                   1909:                simple_unlock(&pvh->pvh_slock);
                   1910:
                   1911:                /*
                   1912:                 * Set up referenced/modified emulation for new mapping.
                   1913:                 */
                   1914:                if ((attrs & PGA_REFERENCED) == 0)
                   1915:                        npte |= PG_FOR | PG_FOW | PG_FOE;
                   1916:                else if ((attrs & PGA_MODIFIED) == 0)
                   1917:                        npte |= PG_FOW;
                   1918:
                   1919:                /* Always force FOE on non-exec mappings. */
                   1920:                if (!pmap_pte_exec(pte))
                   1921:                        npte |= PG_FOE;
                   1922:
                   1923:                /*
                   1924:                 * Mapping was entered on PV list.
                   1925:                 */
                   1926:                npte |= PG_PVLIST;
                   1927:        }
                   1928:        if (wired)
                   1929:                npte |= PG_WIRED;
                   1930: #ifdef DEBUG
                   1931:        if (pmapdebug & PDB_ENTER)
                   1932:                printf("pmap_enter: new pte = 0x%lx\n", npte);
                   1933: #endif
                   1934:
                   1935:        /*
                   1936:         * If the PALcode portion of the new PTE is the same as the
                   1937:         * old PTE, no TBI is necessary.
                   1938:         */
                   1939:        if (PG_PALCODE(opte) == PG_PALCODE(npte))
                   1940:                tflush = FALSE;
                   1941:
                   1942:        /*
                   1943:         * Set the new PTE.
                   1944:         */
                   1945:        PMAP_SET_PTE(pte, npte);
                   1946:
                   1947:        /*
                   1948:         * Invalidate the TLB entry for this VA and any appropriate
                   1949:         * caches.
                   1950:         */
                   1951:        if (tflush) {
                   1952:                PMAP_INVALIDATE_TLB(pmap, va, hadasm, isactive, cpu_id);
                   1953:                PMAP_TLB_SHOOTDOWN(pmap, va, hadasm ? PG_ASM : 0);
                   1954:        }
                   1955:        if (setisync)
                   1956:                PMAP_SET_NEEDISYNC(pmap);
                   1957:        if (needisync)
                   1958:                PMAP_SYNC_ISTREAM(pmap);
                   1959:
                   1960: out:
                   1961:        PMAP_UNLOCK(pmap);
                   1962:        PMAP_MAP_TO_HEAD_UNLOCK();
                   1963:
                   1964:        return error;
                   1965: }
                   1966:
                   1967: /*
                   1968:  * pmap_kenter_pa:             [ INTERFACE ]
                   1969:  *
                   1970:  *     Enter a va -> pa mapping into the kernel pmap without any
                   1971:  *     physical->virtual tracking.
                   1972:  *
                   1973:  *     Note: no locking is necessary in this function.
                   1974:  */
                   1975: void
                   1976: pmap_kenter_pa(vaddr_t va, paddr_t pa, vm_prot_t prot)
                   1977: {
                   1978:        pt_entry_t *pte, npte;
                   1979:        cpuid_t cpu_id = cpu_number();
                   1980:        boolean_t needisync = FALSE;
                   1981:        pmap_t pmap = pmap_kernel();
                   1982:
                   1983: #ifdef DEBUG
                   1984:        if (pmapdebug & (PDB_FOLLOW|PDB_ENTER))
                   1985:                printf("pmap_kenter_pa(%lx, %lx, %x)\n",
                   1986:                    va, pa, prot);
                   1987: #endif
                   1988:
                   1989: #ifdef DIAGNOSTIC
                   1990:        /*
                   1991:         * Sanity check the virtual address.
                   1992:         */
                   1993:        if (va < VM_MIN_KERNEL_ADDRESS)
                   1994:                panic("pmap_kenter_pa: kernel pmap, invalid va 0x%lx", va);
                   1995: #endif
                   1996:
                   1997:        pte = PMAP_KERNEL_PTE(va);
                   1998:
                   1999:        if (pmap_pte_v(pte) == 0)
                   2000:                PMAP_STAT_INCR(pmap->pm_stats.resident_count, 1);
                   2001:        if (pmap_pte_w(pte) == 0)
                   2002:                PMAP_STAT_DECR(pmap->pm_stats.wired_count, 1);
                   2003:
                   2004:        if ((prot & VM_PROT_EXECUTE) != 0 || pmap_pte_exec(pte))
                   2005:                needisync = TRUE;
                   2006:
                   2007:        /*
                   2008:         * Build the new PTE.
                   2009:         */
                   2010:        npte = ((pa >> PGSHIFT) << PG_SHIFT) | pte_prot(pmap_kernel(), prot) |
                   2011:            PG_V | PG_WIRED;
                   2012:
                   2013:        /*
                   2014:         * Set the new PTE.
                   2015:         */
                   2016:        PMAP_SET_PTE(pte, npte);
                   2017: #if defined(MULTIPROCESSOR)
                   2018:        alpha_mb();             /* XXX alpha_wmb()? */
                   2019: #endif
                   2020:
                   2021:        /*
                   2022:         * Invalidate the TLB entry for this VA and any appropriate
                   2023:         * caches.
                   2024:         */
                   2025:        PMAP_INVALIDATE_TLB(pmap, va, TRUE, TRUE, cpu_id);
                   2026:        PMAP_TLB_SHOOTDOWN(pmap, va, PG_ASM);
                   2027:
                   2028:        if (needisync)
                   2029:                PMAP_SYNC_ISTREAM_KERNEL();
                   2030: }
                   2031:
                   2032: /*
                   2033:  * pmap_kremove:               [ INTERFACE ]
                   2034:  *
                   2035:  *     Remove a mapping entered with pmap_kenter_pa()
                   2036:  *     starting at va, for size bytes (assumed to be page rounded).
                   2037:  */
                   2038: void
                   2039: pmap_kremove(vaddr_t va, vsize_t size)
                   2040: {
                   2041:        pt_entry_t *pte;
                   2042:        boolean_t needisync = FALSE;
                   2043:        cpuid_t cpu_id = cpu_number();
                   2044:        pmap_t pmap = pmap_kernel();
                   2045:
                   2046: #ifdef DEBUG
                   2047:        if (pmapdebug & (PDB_FOLLOW|PDB_ENTER))
                   2048:                printf("pmap_kremove(%lx, %lx)\n",
                   2049:                    va, size);
                   2050: #endif
                   2051:
                   2052: #ifdef DIAGNOSTIC
                   2053:        if (va < VM_MIN_KERNEL_ADDRESS)
                   2054:                panic("pmap_kremove: user address");
                   2055: #endif
                   2056:
                   2057:        for (; size != 0; size -= PAGE_SIZE, va += PAGE_SIZE) {
                   2058:                pte = PMAP_KERNEL_PTE(va);
                   2059:                if (pmap_pte_v(pte)) {
                   2060: #ifdef DIAGNOSTIC
                   2061:                        if (pmap_pte_pv(pte))
                   2062:                                panic("pmap_kremove: PG_PVLIST mapping for "
                   2063:                                    "0x%lx", va);
                   2064: #endif
                   2065:                        if (pmap_pte_exec(pte))
                   2066:                                needisync = TRUE;
                   2067:
                   2068:                        /* Zap the mapping. */
                   2069:                        PMAP_SET_PTE(pte, PG_NV);
                   2070: #if defined(MULTIPROCESSOR)
                   2071:                        alpha_mb();             /* XXX alpha_wmb()? */
                   2072: #endif
                   2073:                        PMAP_INVALIDATE_TLB(pmap, va, TRUE, TRUE, cpu_id);
                   2074:                        PMAP_TLB_SHOOTDOWN(pmap, va, PG_ASM);
                   2075:
                   2076:                        /* Update stats. */
                   2077:                        PMAP_STAT_DECR(pmap->pm_stats.resident_count, 1);
                   2078:                        PMAP_STAT_DECR(pmap->pm_stats.wired_count, 1);
                   2079:                }
                   2080:        }
                   2081:
                   2082:        if (needisync)
                   2083:                PMAP_SYNC_ISTREAM_KERNEL();
                   2084: }
                   2085:
                   2086: /*
                   2087:  * pmap_unwire:                        [ INTERFACE ]
                   2088:  *
                   2089:  *     Clear the wired attribute for a map/virtual-address pair.
                   2090:  *
                   2091:  *     The mapping must already exist in the pmap.
                   2092:  */
                   2093: void
                   2094: pmap_unwire(pmap_t pmap, vaddr_t va)
                   2095: {
                   2096:        pt_entry_t *pte;
                   2097:
                   2098: #ifdef DEBUG
                   2099:        if (pmapdebug & PDB_FOLLOW)
                   2100:                printf("pmap_unwire(%p, %lx)\n", pmap, va);
                   2101: #endif
                   2102:        if (pmap == NULL)
                   2103:                return;
                   2104:
                   2105:        PMAP_LOCK(pmap);
                   2106:
                   2107:        pte = pmap_l3pte(pmap, va, NULL);
                   2108: #ifdef DIAGNOSTIC
                   2109:        if (pte == NULL || pmap_pte_v(pte) == 0)
                   2110:                panic("pmap_unwire");
                   2111: #endif
                   2112:
                   2113:        /*
                   2114:         * If wiring actually changed (always?) clear the wire bit and
                   2115:         * update the wire count.  Note that wiring is not a hardware
                   2116:         * characteristic so there is no need to invalidate the TLB.
                   2117:         */
                   2118:        if (pmap_pte_w_chg(pte, 0)) {
                   2119:                pmap_pte_set_w(pte, FALSE);
                   2120:                PMAP_STAT_DECR(pmap->pm_stats.wired_count, 1);
                   2121:        }
                   2122: #ifdef DIAGNOSTIC
                   2123:        else {
                   2124:                printf("pmap_unwire: wiring for pmap %p va 0x%lx "
                   2125:                    "didn't change!\n", pmap, va);
                   2126:        }
                   2127: #endif
                   2128:
                   2129:        PMAP_UNLOCK(pmap);
                   2130: }
                   2131:
                   2132: /*
                   2133:  * pmap_extract:               [ INTERFACE ]
                   2134:  *
                   2135:  *     Extract the physical address associated with the given
                   2136:  *     pmap/virtual address pair.
                   2137:  */
                   2138: boolean_t
                   2139: pmap_extract(pmap_t pmap, vaddr_t va, paddr_t *pap)
                   2140: {
                   2141:        pt_entry_t *l1pte, *l2pte, *l3pte;
                   2142:        boolean_t rv = FALSE;
                   2143:        paddr_t pa;
                   2144:
                   2145: #ifdef DEBUG
                   2146:        if (pmapdebug & PDB_FOLLOW)
                   2147:                printf("pmap_extract(%p, %lx) -> ", pmap, va);
                   2148: #endif
                   2149:
                   2150:        if (pmap == pmap_kernel()) {
                   2151:                if (va < ALPHA_K0SEG_BASE) {
                   2152:                        /* nothing */
                   2153:                } else if (va <= ALPHA_K0SEG_END) {
                   2154:                        pa = ALPHA_K0SEG_TO_PHYS(va);
                   2155:                        rv = TRUE;
                   2156:                } else {
                   2157:                        l3pte = PMAP_KERNEL_PTE(va);
                   2158:                        if (pmap_pte_v(l3pte)) {
                   2159:                                pa = pmap_pte_pa(l3pte) | (va & PGOFSET);
                   2160:                                *pap = pa;
                   2161:                                rv = TRUE;
                   2162:                        }
                   2163:                }
                   2164:                goto out_nolock;
                   2165:        }
                   2166:
                   2167:        PMAP_LOCK(pmap);
                   2168:
                   2169:        l1pte = pmap_l1pte(pmap, va);
                   2170:        if (pmap_pte_v(l1pte) == 0)
                   2171:                goto out;
                   2172:
                   2173:        l2pte = pmap_l2pte(pmap, va, l1pte);
                   2174:        if (pmap_pte_v(l2pte) == 0)
                   2175:                goto out;
                   2176:
                   2177:        l3pte = pmap_l3pte(pmap, va, l2pte);
                   2178:        if (pmap_pte_v(l3pte) == 0)
                   2179:                goto out;
                   2180:
                   2181:        pa = pmap_pte_pa(l3pte) | (va & PGOFSET);
                   2182:        *pap = pa;
                   2183:        rv = TRUE;
                   2184:  out:
                   2185:        PMAP_UNLOCK(pmap);
                   2186:  out_nolock:
                   2187: #ifdef DEBUG
                   2188:        if (pmapdebug & PDB_FOLLOW) {
                   2189:                if (rv)
                   2190:                        printf("0x%lx\n", pa);
                   2191:                else
                   2192:                        printf("failed\n");
                   2193:        }
                   2194: #endif
                   2195:        return (rv);
                   2196: }
                   2197:
                   2198: /*
                   2199:  * pmap_copy:                  [ INTERFACE ]
                   2200:  *
                   2201:  *     Copy the mapping range specified by src_addr/len
                   2202:  *     from the source map to the range dst_addr/len
                   2203:  *     in the destination map.
                   2204:  *
                   2205:  *     This routine is only advisory and need not do anything.
                   2206:  */
                   2207: void
                   2208: pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vaddr_t dst_addr, vsize_t len,
                   2209:     vaddr_t src_addr)
                   2210: {
                   2211: #ifdef DEBUG
                   2212:        if (pmapdebug & PDB_FOLLOW)
                   2213:                printf("pmap_copy(%p, %p, %lx, %lx, %lx)\n",
                   2214:                       dst_pmap, src_pmap, dst_addr, len, src_addr);
                   2215: #endif
                   2216: }
                   2217:
                   2218: /*
                   2219:  * pmap_collect:               [ INTERFACE ]
                   2220:  *
                   2221:  *     Garbage collects the physical map system for pages which are no
                   2222:  *     longer used.  Success need not be guaranteed -- that is, there
                   2223:  *     may well be pages which are not referenced, but others may be
                   2224:  *     collected.
                   2225:  *
                   2226:  *     Called by the pageout daemon when pages are scarce.
                   2227:  */
                   2228: void
                   2229: pmap_collect(pmap_t pmap)
                   2230: {
                   2231:
                   2232: #ifdef DEBUG
                   2233:        if (pmapdebug & PDB_FOLLOW)
                   2234:                printf("pmap_collect(%p)\n", pmap);
                   2235: #endif
                   2236:
                   2237:        /*
                   2238:         * If called for the kernel pmap, just return.  We
                   2239:         * handle this case in the event that we ever want
                   2240:         * to have swappable kernel threads.
                   2241:         */
                   2242:        if (pmap == pmap_kernel())
                   2243:                return;
                   2244:
                   2245:        /*
                   2246:         * This process is about to be swapped out; free all of
                   2247:         * the PT pages by removing the physical mappings for its
                   2248:         * entire address space.  Note: pmap_remove() performs
                   2249:         * all necessary locking.
                   2250:         */
                   2251:        pmap_do_remove(pmap, VM_MIN_ADDRESS, VM_MAX_ADDRESS, FALSE);
                   2252: }
                   2253:
                   2254: /*
                   2255:  * pmap_activate:              [ INTERFACE ]
                   2256:  *
                   2257:  *     Activate the pmap used by the specified process.  This includes
                   2258:  *     reloading the MMU context if the current process, and marking
                   2259:  *     the pmap in use by the processor.
                   2260:  *
                   2261:  *     Note: We may use only spin locks here, since we are called
                   2262:  *     by a critical section in cpu_switch()!
                   2263:  */
                   2264: void
                   2265: pmap_activate(struct proc *p)
                   2266: {
                   2267:        struct pmap *pmap = p->p_vmspace->vm_map.pmap;
                   2268:        cpuid_t cpu_id = cpu_number();
                   2269:
                   2270: #ifdef DEBUG
                   2271:        if (pmapdebug & PDB_FOLLOW)
                   2272:                printf("pmap_activate(%p)\n", p);
                   2273: #endif
                   2274:
                   2275:        /*
                   2276:         * Mark the pmap in use by this processor.
                   2277:         */
                   2278:        atomic_setbits_ulong(&pmap->pm_cpus, (1UL << cpu_id));
                   2279:
                   2280:        /*
                   2281:         * Move the pmap to the end of the LRU list.
                   2282:         */
                   2283:        simple_lock(&pmap_all_pmaps_slock);
                   2284:        TAILQ_REMOVE(&pmap_all_pmaps, pmap, pm_list);
                   2285:        TAILQ_INSERT_TAIL(&pmap_all_pmaps, pmap, pm_list);
                   2286:        simple_unlock(&pmap_all_pmaps_slock);
                   2287:
                   2288:        PMAP_LOCK(pmap);
                   2289:
                   2290:        /*
                   2291:         * Allocate an ASN.
                   2292:         */
                   2293:        pmap_asn_alloc(pmap, cpu_id);
                   2294:
                   2295:        PMAP_ACTIVATE(pmap, p, cpu_id);
                   2296:
                   2297:        PMAP_UNLOCK(pmap);
                   2298: }
                   2299:
                   2300: /*
                   2301:  * pmap_deactivate:            [ INTERFACE ]
                   2302:  *
                   2303:  *     Mark that the pmap used by the specified process is no longer
                   2304:  *     in use by the processor.
                   2305:  *
                   2306:  *     The comment above pmap_activate() wrt. locking applies here,
                   2307:  *     as well.  Note that we use only a single `atomic' operation,
                   2308:  *     so no locking is necessary.
                   2309:  */
                   2310: void
                   2311: pmap_deactivate(struct proc *p)
                   2312: {
                   2313:        struct pmap *pmap = p->p_vmspace->vm_map.pmap;
                   2314:
                   2315: #ifdef DEBUG
                   2316:        if (pmapdebug & PDB_FOLLOW)
                   2317:                printf("pmap_deactivate(%p)\n", p);
                   2318: #endif
                   2319:
                   2320:        /*
                   2321:         * Mark the pmap no longer in use by this processor.
                   2322:         */
                   2323:        atomic_clearbits_ulong(&pmap->pm_cpus, (1UL << cpu_number()));
                   2324: }
                   2325:
                   2326: /*
                   2327:  * pmap_zero_page:             [ INTERFACE ]
                   2328:  *
                   2329:  *     Zero the specified (machine independent) page by mapping the page
                   2330:  *     into virtual memory and clear its contents, one machine dependent
                   2331:  *     page at a time.
                   2332:  *
                   2333:  *     Note: no locking is necessary in this function.
                   2334:  */
                   2335: void
                   2336: pmap_zero_page(struct vm_page *pg)
                   2337: {
                   2338:        paddr_t phys = VM_PAGE_TO_PHYS(pg);
                   2339:        u_long *p0, *p1, *pend;
                   2340:
                   2341: #ifdef DEBUG
                   2342:        if (pmapdebug & PDB_FOLLOW)
                   2343:                printf("pmap_zero_page(%lx)\n", phys);
                   2344: #endif
                   2345:
                   2346:        p0 = (u_long *)ALPHA_PHYS_TO_K0SEG(phys);
                   2347:        pend = (u_long *)((u_long)p0 + PAGE_SIZE);
                   2348:
                   2349:        /*
                   2350:         * Unroll the loop a bit, doing 16 quadwords per iteration.
                   2351:         * Do only 8 back-to-back stores, and alternate registers.
                   2352:         */
                   2353:        do {
                   2354:                __asm __volatile(
                   2355:                "# BEGIN loop body\n"
                   2356:                "       addq    %2, (8 * 8), %1         \n"
                   2357:                "       stq     $31, (0 * 8)(%0)        \n"
                   2358:                "       stq     $31, (1 * 8)(%0)        \n"
                   2359:                "       stq     $31, (2 * 8)(%0)        \n"
                   2360:                "       stq     $31, (3 * 8)(%0)        \n"
                   2361:                "       stq     $31, (4 * 8)(%0)        \n"
                   2362:                "       stq     $31, (5 * 8)(%0)        \n"
                   2363:                "       stq     $31, (6 * 8)(%0)        \n"
                   2364:                "       stq     $31, (7 * 8)(%0)        \n"
                   2365:                "                                       \n"
                   2366:                "       addq    %3, (8 * 8), %0         \n"
                   2367:                "       stq     $31, (0 * 8)(%1)        \n"
                   2368:                "       stq     $31, (1 * 8)(%1)        \n"
                   2369:                "       stq     $31, (2 * 8)(%1)        \n"
                   2370:                "       stq     $31, (3 * 8)(%1)        \n"
                   2371:                "       stq     $31, (4 * 8)(%1)        \n"
                   2372:                "       stq     $31, (5 * 8)(%1)        \n"
                   2373:                "       stq     $31, (6 * 8)(%1)        \n"
                   2374:                "       stq     $31, (7 * 8)(%1)        \n"
                   2375:                "       # END loop body"
                   2376:                : "=r" (p0), "=r" (p1)
                   2377:                : "0" (p0), "1" (p1)
                   2378:                : "memory");
                   2379:        } while (p0 < pend);
                   2380: }
                   2381:
                   2382: /*
                   2383:  * pmap_copy_page:             [ INTERFACE ]
                   2384:  *
                   2385:  *     Copy the specified (machine independent) page by mapping the page
                   2386:  *     into virtual memory and using memcpy to copy the page, one machine
                   2387:  *     dependent page at a time.
                   2388:  *
                   2389:  *     Note: no locking is necessary in this function.
                   2390:  */
                   2391: void
                   2392: pmap_copy_page(struct vm_page *srcpg, struct vm_page *dstpg)
                   2393: {
                   2394:        paddr_t src = VM_PAGE_TO_PHYS(srcpg);
                   2395:        paddr_t dst = VM_PAGE_TO_PHYS(dstpg);
                   2396:        caddr_t s, d;
                   2397:
                   2398: #ifdef DEBUG
                   2399:        if (pmapdebug & PDB_FOLLOW)
                   2400:                printf("pmap_copy_page(%lx, %lx)\n", src, dst);
                   2401: #endif
                   2402:         s = (caddr_t)ALPHA_PHYS_TO_K0SEG(src);
                   2403:         d = (caddr_t)ALPHA_PHYS_TO_K0SEG(dst);
                   2404:        memcpy(d, s, PAGE_SIZE);
                   2405: }
                   2406:
                   2407: /*
                   2408:  * pmap_clear_modify:          [ INTERFACE ]
                   2409:  *
                   2410:  *     Clear the modify bits on the specified physical page.
                   2411:  */
                   2412: boolean_t
                   2413: pmap_clear_modify(struct vm_page *pg)
                   2414: {
                   2415:        struct pv_head *pvh;
                   2416:        paddr_t pa = VM_PAGE_TO_PHYS(pg);
                   2417:        boolean_t rv = FALSE;
                   2418:        cpuid_t cpu_id = cpu_number();
                   2419:
                   2420: #ifdef DEBUG
                   2421:        if (pmapdebug & PDB_FOLLOW)
                   2422:                printf("pmap_clear_modify(%p)\n", pg);
                   2423: #endif
                   2424:
                   2425:        pvh = pa_to_pvh(pa);
                   2426:
                   2427:        PMAP_HEAD_TO_MAP_LOCK();
                   2428:        simple_lock(&pvh->pvh_slock);
                   2429:
                   2430:        if (pvh->pvh_attrs & PGA_MODIFIED) {
                   2431:                rv = TRUE;
                   2432:                pmap_changebit(pa, PG_FOW, ~0, cpu_id);
                   2433:                pvh->pvh_attrs &= ~PGA_MODIFIED;
                   2434:        }
                   2435:
                   2436:        simple_unlock(&pvh->pvh_slock);
                   2437:        PMAP_HEAD_TO_MAP_UNLOCK();
                   2438:
                   2439:        return (rv);
                   2440: }
                   2441:
                   2442: /*
                   2443:  * pmap_clear_reference:       [ INTERFACE ]
                   2444:  *
                   2445:  *     Clear the reference bit on the specified physical page.
                   2446:  */
                   2447: boolean_t
                   2448: pmap_clear_reference(struct vm_page *pg)
                   2449: {
                   2450:        struct pv_head *pvh;
                   2451:        paddr_t pa = VM_PAGE_TO_PHYS(pg);
                   2452:        boolean_t rv = FALSE;
                   2453:        cpuid_t cpu_id = cpu_number();
                   2454:
                   2455: #ifdef DEBUG
                   2456:        if (pmapdebug & PDB_FOLLOW)
                   2457:                printf("pmap_clear_reference(%p)\n", pg);
                   2458: #endif
                   2459:
                   2460:        pvh = pa_to_pvh(pa);
                   2461:
                   2462:        PMAP_HEAD_TO_MAP_LOCK();
                   2463:        simple_lock(&pvh->pvh_slock);
                   2464:
                   2465:        if (pvh->pvh_attrs & PGA_REFERENCED) {
                   2466:                rv = TRUE;
                   2467:                pmap_changebit(pa, PG_FOR | PG_FOW | PG_FOE, ~0, cpu_id);
                   2468:                pvh->pvh_attrs &= ~PGA_REFERENCED;
                   2469:        }
                   2470:
                   2471:        simple_unlock(&pvh->pvh_slock);
                   2472:        PMAP_HEAD_TO_MAP_UNLOCK();
                   2473:
                   2474:        return (rv);
                   2475: }
                   2476:
                   2477: /*
                   2478:  * pmap_is_referenced:         [ INTERFACE ]
                   2479:  *
                   2480:  *     Return whether or not the specified physical page is referenced
                   2481:  *     by any physical maps.
                   2482:  */
                   2483: boolean_t
                   2484: pmap_is_referenced(struct vm_page *pg)
                   2485: {
                   2486:        struct pv_head *pvh;
                   2487:        paddr_t pa = VM_PAGE_TO_PHYS(pg);
                   2488:        boolean_t rv;
                   2489:
                   2490:        pvh = pa_to_pvh(pa);
                   2491:        rv = ((pvh->pvh_attrs & PGA_REFERENCED) != 0);
                   2492: #ifdef DEBUG
                   2493:        if (pmapdebug & PDB_FOLLOW) {
                   2494:                printf("pmap_is_referenced(%p) -> %c\n", pg, "FT"[rv]);
                   2495:        }
                   2496: #endif
                   2497:        return (rv);
                   2498: }
                   2499:
                   2500: /*
                   2501:  * pmap_is_modified:           [ INTERFACE ]
                   2502:  *
                   2503:  *     Return whether or not the specified physical page is modified
                   2504:  *     by any physical maps.
                   2505:  */
                   2506: boolean_t
                   2507: pmap_is_modified(struct vm_page *pg)
                   2508: {
                   2509:        struct pv_head *pvh;
                   2510:        paddr_t pa = VM_PAGE_TO_PHYS(pg);
                   2511:        boolean_t rv;
                   2512:
                   2513:        pvh = pa_to_pvh(pa);
                   2514:        rv = ((pvh->pvh_attrs & PGA_MODIFIED) != 0);
                   2515: #ifdef DEBUG
                   2516:        if (pmapdebug & PDB_FOLLOW) {
                   2517:                printf("pmap_is_modified(%p) -> %c\n", pg, "FT"[rv]);
                   2518:        }
                   2519: #endif
                   2520:        return (rv);
                   2521: }
                   2522:
                   2523: /*
                   2524:  * Miscellaneous support routines follow
                   2525:  */
                   2526:
                   2527: /*
                   2528:  * alpha_protection_init:
                   2529:  *
                   2530:  *     Initialize Alpha protection code array.
                   2531:  *
                   2532:  *     Note: no locking is necessary in this function.
                   2533:  */
                   2534: void
                   2535: alpha_protection_init(void)
                   2536: {
                   2537:        int prot, *kp, *up;
                   2538:
                   2539:        kp = protection_codes[0];
                   2540:        up = protection_codes[1];
                   2541:
                   2542:        for (prot = 0; prot < 8; prot++) {
                   2543:                kp[prot] = 0; up[prot] = 0;
                   2544:                switch (prot) {
                   2545:                case VM_PROT_NONE | VM_PROT_NONE | VM_PROT_NONE:
                   2546:                        kp[prot] |= PG_ASM;
                   2547:                        up[prot] |= 0;
                   2548:                        break;
                   2549:
                   2550:                case VM_PROT_READ | VM_PROT_NONE | VM_PROT_EXECUTE:
                   2551:                case VM_PROT_NONE | VM_PROT_NONE | VM_PROT_EXECUTE:
                   2552:                        kp[prot] |= PG_EXEC;            /* software */
                   2553:                        up[prot] |= PG_EXEC;            /* software */
                   2554:                        /* FALLTHROUGH */
                   2555:
                   2556:                case VM_PROT_READ | VM_PROT_NONE | VM_PROT_NONE:
                   2557:                        kp[prot] |= PG_ASM | PG_KRE;
                   2558:                        up[prot] |= PG_URE | PG_KRE;
                   2559:                        break;
                   2560:
                   2561:                case VM_PROT_NONE | VM_PROT_WRITE | VM_PROT_NONE:
                   2562:                        kp[prot] |= PG_ASM | PG_KWE;
                   2563:                        up[prot] |= PG_UWE | PG_KWE;
                   2564:                        break;
                   2565:
                   2566:                case VM_PROT_NONE | VM_PROT_WRITE | VM_PROT_EXECUTE:
                   2567:                case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE:
                   2568:                        kp[prot] |= PG_EXEC;            /* software */
                   2569:                        up[prot] |= PG_EXEC;            /* software */
                   2570:                        /* FALLTHROUGH */
                   2571:
                   2572:                case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_NONE:
                   2573:                        kp[prot] |= PG_ASM | PG_KWE | PG_KRE;
                   2574:                        up[prot] |= PG_UWE | PG_URE | PG_KWE | PG_KRE;
                   2575:                        break;
                   2576:                }
                   2577:        }
                   2578: }
                   2579:
                   2580: /*
                   2581:  * pmap_remove_mapping:
                   2582:  *
                   2583:  *     Invalidate a single page denoted by pmap/va.
                   2584:  *
                   2585:  *     If (pte != NULL), it is the already computed PTE for the page.
                   2586:  *
                   2587:  *     Note: locking in this function is complicated by the fact
                   2588:  *     that we can be called when the PV list is already locked.
                   2589:  *     (pmap_page_protect()).  In this case, the caller must be
                   2590:  *     careful to get the next PV entry while we remove this entry
                   2591:  *     from beneath it.  We assume that the pmap itself is already
                   2592:  *     locked; dolock applies only to the PV list.
                   2593:  *
                   2594:  *     Returns TRUE or FALSE, indicating if an I-stream sync needs
                   2595:  *     to be initiated (for this CPU or for other CPUs).
                   2596:  */
                   2597: boolean_t
                   2598: pmap_remove_mapping(pmap_t pmap, vaddr_t va, pt_entry_t *pte,
                   2599:     boolean_t dolock, cpuid_t cpu_id, struct prm_thief *prmt)
                   2600: {
                   2601:        paddr_t pa;
                   2602:        boolean_t onpv;
                   2603:        boolean_t hadasm;
                   2604:        boolean_t isactive;
                   2605:        boolean_t needisync = FALSE;
                   2606:        struct pv_entry **pvp;
                   2607:        pt_entry_t **ptp;
                   2608:
                   2609: #ifdef DEBUG
                   2610:        if (pmapdebug & (PDB_FOLLOW|PDB_REMOVE|PDB_PROTECT))
                   2611:                printf("pmap_remove_mapping(%p, %lx, %p, %d, %ld, %p)\n",
                   2612:                       pmap, va, pte, dolock, cpu_id, pvp);
                   2613: #endif
                   2614:
                   2615:        if (prmt != NULL) {
                   2616:                if (prmt->prmt_flags & PRMT_PV)
                   2617:                        pvp = &prmt->prmt_pv;
                   2618:                else
                   2619:                        pvp = NULL;
                   2620:                if (prmt->prmt_flags & PRMT_PTP)
                   2621:                        ptp = &prmt->prmt_ptp;
                   2622:                else
                   2623:                        ptp = NULL;
                   2624:        } else {
                   2625:                pvp = NULL;
                   2626:                ptp = NULL;
                   2627:        }
                   2628:
                   2629:        /*
                   2630:         * PTE not provided, compute it from pmap and va.
                   2631:         */
                   2632:        if (pte == PT_ENTRY_NULL) {
                   2633:                pte = pmap_l3pte(pmap, va, NULL);
                   2634:                if (pmap_pte_v(pte) == 0)
                   2635:                        return (FALSE);
                   2636:        }
                   2637:
                   2638:        pa = pmap_pte_pa(pte);
                   2639:        onpv = (pmap_pte_pv(pte) != 0);
                   2640:        hadasm = (pmap_pte_asm(pte) != 0);
                   2641:        isactive = PMAP_ISACTIVE(pmap, cpu_id);
                   2642:
                   2643:        /*
                   2644:         * Determine what we need to do about the I-stream.  If
                   2645:         * PG_EXEC was set, we mark a user pmap as needing an
                   2646:         * I-sync on the way out to userspace.  We always need
                   2647:         * an immediate I-sync for the kernel pmap.
                   2648:         */
                   2649:        if (pmap_pte_exec(pte)) {
                   2650:                if (pmap == pmap_kernel())
                   2651:                        needisync = TRUE;
                   2652:                else {
                   2653:                        PMAP_SET_NEEDISYNC(pmap);
                   2654:                        needisync = (pmap->pm_cpus != 0);
                   2655:                }
                   2656:        }
                   2657:
                   2658:        /*
                   2659:         * Update statistics
                   2660:         */
                   2661:        if (pmap_pte_w(pte))
                   2662:                PMAP_STAT_DECR(pmap->pm_stats.wired_count, 1);
                   2663:        PMAP_STAT_DECR(pmap->pm_stats.resident_count, 1);
                   2664:
                   2665:        /*
                   2666:         * Invalidate the PTE after saving the reference modify info.
                   2667:         */
                   2668: #ifdef DEBUG
                   2669:        if (pmapdebug & PDB_REMOVE)
                   2670:                printf("remove: invalidating pte at %p\n", pte);
                   2671: #endif
                   2672:        PMAP_SET_PTE(pte, PG_NV);
                   2673:
                   2674:        PMAP_INVALIDATE_TLB(pmap, va, hadasm, isactive, cpu_id);
                   2675:        PMAP_TLB_SHOOTDOWN(pmap, va, hadasm ? PG_ASM : 0);
                   2676:
                   2677:        /*
                   2678:         * If we're removing a user mapping, check to see if we
                   2679:         * can free page table pages.
                   2680:         */
                   2681:        if (pmap != pmap_kernel()) {
                   2682:                /*
                   2683:                 * Delete the reference on the level 3 table.  It will
                   2684:                 * delete references on the level 2 and 1 tables as
                   2685:                 * appropriate.
                   2686:                 */
                   2687:                pmap_l3pt_delref(pmap, va, pte, cpu_id, ptp);
                   2688:        }
                   2689:
                   2690:        /*
                   2691:         * If the mapping wasn't entered on the PV list, we're all done.
                   2692:         */
                   2693:        if (onpv == FALSE) {
                   2694: #ifdef DIAGNOSTIC
                   2695:                if (pvp != NULL)
                   2696:                        panic("pmap_removing_mapping: onpv / pvp inconsistent");
                   2697: #endif
                   2698:                return (needisync);
                   2699:        }
                   2700:
                   2701:        /*
                   2702:         * Remove it from the PV table.
                   2703:         */
                   2704:        pmap_pv_remove(pmap, pa, va, dolock, pvp);
                   2705:
                   2706:        return (needisync);
                   2707: }
                   2708:
                   2709: /*
                   2710:  * pmap_changebit:
                   2711:  *
                   2712:  *     Set or clear the specified PTE bits for all mappings on the
                   2713:  *     specified page.
                   2714:  *
                   2715:  *     Note: we assume that the pv_head is already locked, and that
                   2716:  *     the caller has acquired a PV->pmap mutex so that we can lock
                   2717:  *     the pmaps as we encounter them.
                   2718:  *
                   2719:  *     XXX This routine could stand to have some I-stream
                   2720:  *     XXX optimization done.
                   2721:  */
                   2722: void
                   2723: pmap_changebit(paddr_t pa, u_long set, u_long mask, cpuid_t cpu_id)
                   2724: {
                   2725:        struct pv_head *pvh;
                   2726:        pv_entry_t pv;
                   2727:        pt_entry_t *pte, npte;
                   2728:        vaddr_t va;
                   2729:        boolean_t hadasm, isactive;
                   2730:        boolean_t needisync, needkisync = FALSE;
                   2731:
                   2732: #ifdef DEBUG
                   2733:        if (pmapdebug & PDB_BITS)
                   2734:                printf("pmap_changebit(0x%lx, 0x%lx, 0x%lx)\n",
                   2735:                    pa, set, mask);
                   2736: #endif
                   2737:        if (!PAGE_IS_MANAGED(pa))
                   2738:                return;
                   2739:
                   2740:        pvh = pa_to_pvh(pa);
                   2741:        /*
                   2742:         * Loop over all current mappings setting/clearing as appropriate.
                   2743:         */
                   2744:        for (pv = LIST_FIRST(&pvh->pvh_list); pv != NULL;
                   2745:             pv = LIST_NEXT(pv, pv_list)) {
                   2746:                va = pv->pv_va;
                   2747:
                   2748:                /*
                   2749:                 * XXX don't write protect pager mappings
                   2750:                 */
                   2751:                if (pv->pv_pmap == pmap_kernel() &&
                   2752: /* XXX */          mask == ~(PG_KWE | PG_UWE)) {
                   2753:                        if (va >= uvm.pager_sva && va < uvm.pager_eva)
                   2754:                                continue;
                   2755:                }
                   2756:
                   2757:                PMAP_LOCK(pv->pv_pmap);
                   2758:
                   2759:                pte = pv->pv_pte;
                   2760:                npte = (*pte | set) & mask;
                   2761:                if (*pte != npte) {
                   2762:                        hadasm = (pmap_pte_asm(pte) != 0);
                   2763:                        isactive = PMAP_ISACTIVE(pv->pv_pmap, cpu_id);
                   2764:                        /*
                   2765:                         * Determine what we need to do about the I-stream.
                   2766:                         * If PG_EXEC was set, we mark a user pmap as needing
                   2767:                         * an I-sync on the way out to userspace.  We always
                   2768:                         * need an immediate I-sync for the kernel pmap.
                   2769:                         */
                   2770:                        needisync = FALSE;
                   2771:                        if (pmap_pte_exec(pte)) {
                   2772:                                if (pv->pv_pmap == pmap_kernel())
                   2773:                                        needkisync = TRUE;
                   2774:                                else {
                   2775:                                        PMAP_SET_NEEDISYNC(pv->pv_pmap);
                   2776:                                        if (pv->pv_pmap->pm_cpus != 0)
                   2777:                                                needisync = TRUE;
                   2778:                                }
                   2779:                        } else {
                   2780:                                /* Never clear FOE on non-exec mappings. */
                   2781:                                npte |= PG_FOE;
                   2782:                        }
                   2783:                        PMAP_SET_PTE(pte, npte);
                   2784:                        if (needisync)
                   2785:                                PMAP_SYNC_ISTREAM_USER(pv->pv_pmap);
                   2786:                        PMAP_INVALIDATE_TLB(pv->pv_pmap, va, hadasm, isactive,
                   2787:                            cpu_id);
                   2788:                        PMAP_TLB_SHOOTDOWN(pv->pv_pmap, va,
                   2789:                            hadasm ? PG_ASM : 0);
                   2790:                }
                   2791:                PMAP_UNLOCK(pv->pv_pmap);
                   2792:        }
                   2793:
                   2794:        if (needkisync)
                   2795:                PMAP_SYNC_ISTREAM_KERNEL();
                   2796: }
                   2797:
                   2798: /*
                   2799:  * pmap_emulate_reference:
                   2800:  *
                   2801:  *     Emulate reference and/or modified bit hits.
                   2802:  *
                   2803:  *     return non-zero if this was a FOE fault and the pte is not
                   2804:  *     executable.
                   2805:  */
                   2806: int
                   2807: pmap_emulate_reference(struct proc *p, vaddr_t v, int user, int type)
                   2808: {
                   2809:        pt_entry_t faultoff, *pte;
                   2810:        paddr_t pa;
                   2811:        struct pv_head *pvh;
                   2812:        boolean_t didlock = FALSE;
                   2813:        cpuid_t cpu_id = cpu_number();
                   2814:
                   2815: #ifdef DEBUG
                   2816:        if (pmapdebug & PDB_FOLLOW)
                   2817:                printf("pmap_emulate_reference: %p, 0x%lx, %d, %d\n",
                   2818:                    p, v, user, type);
                   2819: #endif
                   2820:
                   2821:        /*
                   2822:         * Convert process and virtual address to physical address.
                   2823:         */
                   2824:        if (v >= VM_MIN_KERNEL_ADDRESS) {
                   2825:                if (user)
                   2826:                        panic("pmap_emulate_reference: user ref to kernel");
                   2827:                /*
                   2828:                 * No need to lock here; kernel PT pages never go away.
                   2829:                 */
                   2830:                pte = PMAP_KERNEL_PTE(v);
                   2831:        } else {
                   2832: #ifdef DIAGNOSTIC
                   2833:                if (p == NULL)
                   2834:                        panic("pmap_emulate_reference: bad proc");
                   2835:                if (p->p_vmspace == NULL)
                   2836:                        panic("pmap_emulate_reference: bad p_vmspace");
                   2837: #endif
                   2838:                PMAP_LOCK(p->p_vmspace->vm_map.pmap);
                   2839:                didlock = TRUE;
                   2840:                pte = pmap_l3pte(p->p_vmspace->vm_map.pmap, v, NULL);
                   2841:                /*
                   2842:                 * We'll unlock below where we're done with the PTE.
                   2843:                 */
                   2844:        }
                   2845:        if (!pmap_pte_exec(pte) && type == ALPHA_MMCSR_FOE) {
                   2846:                if (didlock)
                   2847:                        PMAP_UNLOCK(p->p_vmspace->vm_map.pmap);
                   2848:                return (1);
                   2849:        }
                   2850: #ifdef DEBUG
                   2851:        if (pmapdebug & PDB_FOLLOW) {
                   2852:                printf("\tpte = %p, ", pte);
                   2853:                printf("*pte = 0x%lx\n", *pte);
                   2854:        }
                   2855: #endif
                   2856: #ifdef DEBUG                           /* These checks are more expensive */
                   2857:        if (!pmap_pte_v(pte))
                   2858:                panic("pmap_emulate_reference: invalid pte");
                   2859: #if 0
                   2860:        /*
                   2861:         * Can't do these, because cpu_fork call pmap_emulate_reference(),
                   2862:         * and the bits aren't guaranteed, for them...
                   2863:         */
                   2864:        if (type == ALPHA_MMCSR_FOW) {
                   2865:                if (!(*pte & (user ? PG_UWE : PG_UWE | PG_KWE)))
                   2866:                        panic("pmap_emulate_reference: write but unwritable");
                   2867:                if (!(*pte & PG_FOW))
                   2868:                        panic("pmap_emulate_reference: write but not FOW");
                   2869:        } else {
                   2870:                if (!(*pte & (user ? PG_URE : PG_URE | PG_KRE)))
                   2871:                        panic("pmap_emulate_reference: !write but unreadable");
                   2872:                if (!(*pte & (PG_FOR | PG_FOE)))
                   2873:                        panic("pmap_emulate_reference: !write but not FOR|FOE");
                   2874:        }
                   2875: #endif
                   2876:        /* Other diagnostics? */
                   2877: #endif
                   2878:        pa = pmap_pte_pa(pte);
                   2879:
                   2880:        /*
                   2881:         * We're now done with the PTE.  If it was a user pmap, unlock
                   2882:         * it now.
                   2883:         */
                   2884:        if (didlock)
                   2885:                PMAP_UNLOCK(p->p_vmspace->vm_map.pmap);
                   2886:
                   2887: #ifdef DEBUG
                   2888:        if (pmapdebug & PDB_FOLLOW)
                   2889:                printf("\tpa = 0x%lx\n", pa);
                   2890: #endif
                   2891: #ifdef DIAGNOSTIC
                   2892:        if (!PAGE_IS_MANAGED(pa))
                   2893:                panic("pmap_emulate_reference(%p, 0x%lx, %d, %d): pa 0x%lx not managed", p, v, user, type, pa);
                   2894: #endif
                   2895:
                   2896:        /*
                   2897:         * Twiddle the appropriate bits to reflect the reference
                   2898:         * and/or modification..
                   2899:         *
                   2900:         * The rules:
                   2901:         *      (1) always mark page as used, and
                   2902:         *      (2) if it was a write fault, mark page as modified.
                   2903:         */
                   2904:        pvh = pa_to_pvh(pa);
                   2905:
                   2906:        PMAP_HEAD_TO_MAP_LOCK();
                   2907:        simple_lock(&pvh->pvh_slock);
                   2908:
                   2909:        if (type == ALPHA_MMCSR_FOW) {
                   2910:                pvh->pvh_attrs |= (PGA_REFERENCED|PGA_MODIFIED);
                   2911:                faultoff = PG_FOR | PG_FOW | PG_FOE;
                   2912:        } else {
                   2913:                pvh->pvh_attrs |= PGA_REFERENCED;
                   2914:                faultoff = PG_FOR | PG_FOE;
                   2915:        }
                   2916:        /*
                   2917:         * If the page is not PG_EXEC, pmap_changebit will automagically
                   2918:         * set PG_FOE (gross, but necessary if I don't want to change the
                   2919:         * whole API).
                   2920:         */
                   2921:        pmap_changebit(pa, 0, ~faultoff, cpu_id);
                   2922:
                   2923:        simple_unlock(&pvh->pvh_slock);
                   2924:        PMAP_HEAD_TO_MAP_UNLOCK();
                   2925:
                   2926:        return (0);
                   2927: }
                   2928:
                   2929: #ifdef DEBUG
                   2930: /*
                   2931:  * pmap_pv_dump:
                   2932:  *
                   2933:  *     Dump the physical->virtual data for the specified page.
                   2934:  */
                   2935: void
                   2936: pmap_pv_dump(paddr_t pa)
                   2937: {
                   2938:        struct pv_head *pvh;
                   2939:        pv_entry_t pv;
                   2940:        static const char *usage[] = {
                   2941:                "normal", "pvent", "l1pt", "l2pt", "l3pt",
                   2942:        };
                   2943:
                   2944:        pvh = pa_to_pvh(pa);
                   2945:
                   2946:        simple_lock(&pvh->pvh_slock);
                   2947:
                   2948:        printf("pa 0x%lx (attrs = 0x%x, usage = " /* ) */, pa, pvh->pvh_attrs);
                   2949:        if (pvh->pvh_usage < PGU_NORMAL || pvh->pvh_usage > PGU_L3PT)
                   2950: /* ( */                printf("??? %d):\n", pvh->pvh_usage);
                   2951:        else
                   2952: /* ( */                printf("%s):\n", usage[pvh->pvh_usage]);
                   2953:
                   2954:        for (pv = LIST_FIRST(&pvh->pvh_list); pv != NULL;
                   2955:             pv = LIST_NEXT(pv, pv_list))
                   2956:                printf("     pmap %p, va 0x%lx\n",
                   2957:                    pv->pv_pmap, pv->pv_va);
                   2958:        printf("\n");
                   2959:
                   2960:        simple_unlock(&pvh->pvh_slock);
                   2961: }
                   2962: #endif
                   2963:
                   2964: /*
                   2965:  * vtophys:
                   2966:  *
                   2967:  *     Return the physical address corresponding to the K0SEG or
                   2968:  *     K1SEG address provided.
                   2969:  *
                   2970:  *     Note: no locking is necessary in this function.
                   2971:  */
                   2972: paddr_t
                   2973: vtophys(vaddr_t vaddr)
                   2974: {
                   2975:        pt_entry_t *pte;
                   2976:        paddr_t paddr = 0;
                   2977:
                   2978:        if (vaddr < ALPHA_K0SEG_BASE)
                   2979:                printf("vtophys: invalid vaddr 0x%lx", vaddr);
                   2980:        else if (vaddr <= ALPHA_K0SEG_END)
                   2981:                paddr = ALPHA_K0SEG_TO_PHYS(vaddr);
                   2982:        else {
                   2983:                pte = PMAP_KERNEL_PTE(vaddr);
                   2984:                if (pmap_pte_v(pte))
                   2985:                        paddr = pmap_pte_pa(pte) | (vaddr & PGOFSET);
                   2986:        }
                   2987:
                   2988: #if 0
                   2989:        printf("vtophys(0x%lx) -> 0x%lx\n", vaddr, paddr);
                   2990: #endif
                   2991:
                   2992:        return (paddr);
                   2993: }
                   2994:
                   2995: /******************** pv_entry management ********************/
                   2996:
                   2997: /*
                   2998:  * pmap_pv_enter:
                   2999:  *
                   3000:  *     Add a physical->virtual entry to the pv_table.
                   3001:  */
                   3002: int
                   3003: pmap_pv_enter(pmap_t pmap, paddr_t pa, vaddr_t va, pt_entry_t *pte,
                   3004:     boolean_t dolock)
                   3005: {
                   3006:        struct pv_head *pvh;
                   3007:        pv_entry_t newpv;
                   3008:
                   3009:        /*
                   3010:         * Allocate and fill in the new pv_entry.
                   3011:         */
                   3012:        newpv = pmap_pv_alloc();
                   3013:        if (newpv == NULL)
                   3014:                return (ENOMEM);
                   3015:        newpv->pv_va = va;
                   3016:        newpv->pv_pmap = pmap;
                   3017:        newpv->pv_pte = pte;
                   3018:
                   3019:        pvh = pa_to_pvh(pa);
                   3020:
                   3021:        if (dolock)
                   3022:                simple_lock(&pvh->pvh_slock);
                   3023:
                   3024: #ifdef DEBUG
                   3025:        {
                   3026:        pv_entry_t pv;
                   3027:        /*
                   3028:         * Make sure the entry doesn't already exist.
                   3029:         */
                   3030:        for (pv = LIST_FIRST(&pvh->pvh_list); pv != NULL;
                   3031:             pv = LIST_NEXT(pv, pv_list))
                   3032:                if (pmap == pv->pv_pmap && va == pv->pv_va) {
                   3033:                        printf("pmap = %p, va = 0x%lx\n", pmap, va);
                   3034:                        panic("pmap_pv_enter: already in pv table");
                   3035:                }
                   3036:        }
                   3037: #endif
                   3038:
                   3039:        /*
                   3040:         * ...and put it in the list.
                   3041:         */
                   3042:        LIST_INSERT_HEAD(&pvh->pvh_list, newpv, pv_list);
                   3043:
                   3044:        if (dolock)
                   3045:                simple_unlock(&pvh->pvh_slock);
                   3046:
                   3047:        return (0);
                   3048: }
                   3049:
                   3050: /*
                   3051:  * pmap_pv_remove:
                   3052:  *
                   3053:  *     Remove a physical->virtual entry from the pv_table.
                   3054:  */
                   3055: void
                   3056: pmap_pv_remove(pmap_t pmap, paddr_t pa, vaddr_t va, boolean_t dolock,
                   3057:     struct pv_entry **pvp)
                   3058: {
                   3059:        struct pv_head *pvh;
                   3060:        pv_entry_t pv;
                   3061:
                   3062:        pvh = pa_to_pvh(pa);
                   3063:
                   3064:        if (dolock)
                   3065:                simple_lock(&pvh->pvh_slock);
                   3066:
                   3067:        /*
                   3068:         * Find the entry to remove.
                   3069:         */
                   3070:        for (pv = LIST_FIRST(&pvh->pvh_list); pv != NULL;
                   3071:             pv = LIST_NEXT(pv, pv_list))
                   3072:                if (pmap == pv->pv_pmap && va == pv->pv_va)
                   3073:                        break;
                   3074:
                   3075: #ifdef DEBUG
                   3076:        if (pv == NULL)
                   3077:                panic("pmap_pv_remove: not in pv table");
                   3078: #endif
                   3079:
                   3080:        LIST_REMOVE(pv, pv_list);
                   3081:
                   3082:        if (dolock)
                   3083:                simple_unlock(&pvh->pvh_slock);
                   3084:
                   3085:        /*
                   3086:         * If pvp is not NULL, this is pmap_pv_alloc() stealing an
                   3087:         * entry from another mapping, and we return the now unused
                   3088:         * entry in it.  Otherwise, free the pv_entry.
                   3089:         */
                   3090:        if (pvp != NULL)
                   3091:                *pvp = pv;
                   3092:        else
                   3093:                pmap_pv_free(pv);
                   3094: }
                   3095:
                   3096: /*
                   3097:  * pmap_pv_alloc:
                   3098:  *
                   3099:  *     Allocate a pv_entry.
                   3100:  */
                   3101: struct pv_entry *
                   3102: pmap_pv_alloc(void)
                   3103: {
                   3104:        struct pv_head *pvh;
                   3105:        struct pv_entry *pv;
                   3106:        int bank, npg, pg;
                   3107:        pt_entry_t *pte;
                   3108:        pmap_t pvpmap;
                   3109:        cpuid_t cpu_id;
                   3110:        struct prm_thief prmt;
                   3111:
                   3112:        pv = pool_get(&pmap_pv_pool, PR_NOWAIT);
                   3113:        if (pv != NULL)
                   3114:                return (pv);
                   3115:
                   3116:        prmt.prmt_flags = PRMT_PV;
                   3117:
                   3118:        /*
                   3119:         * We were unable to allocate one from the pool.  Try to
                   3120:         * steal one from another mapping.  At this point we know that:
                   3121:         *
                   3122:         *      (1) We have not locked the pv table, and we already have
                   3123:         *          the map-to-head lock, so it is safe for us to do so here.
                   3124:         *
                   3125:         *      (2) The pmap that wants this entry *is* locked.  We must
                   3126:         *          use simple_lock_try() to prevent deadlock from occurring.
                   3127:         *
                   3128:         * XXX Note that in case #2, there is an exception; it *is* safe to
                   3129:         * steal a mapping from the pmap that wants this entry!  We may want
                   3130:         * to consider passing the pmap to this function so that we can take
                   3131:         * advantage of this.
                   3132:         */
                   3133:
                   3134:        /* XXX This search could probably be improved. */
                   3135:        for (bank = 0; bank < vm_nphysseg; bank++) {
                   3136:                npg = vm_physmem[bank].end - vm_physmem[bank].start;
                   3137:                for (pg = 0; pg < npg; pg++) {
                   3138:                        pvh = &vm_physmem[bank].pmseg.pvhead[pg];
                   3139:                        simple_lock(&pvh->pvh_slock);
                   3140:                        for (pv = LIST_FIRST(&pvh->pvh_list);
                   3141:                             pv != NULL; pv = LIST_NEXT(pv, pv_list)) {
                   3142:                                pvpmap = pv->pv_pmap;
                   3143:
                   3144:                                /* Don't steal from kernel pmap. */
                   3145:                                if (pvpmap == pmap_kernel())
                   3146:                                        continue;
                   3147:
                   3148:                                if (simple_lock_try(&pvpmap->pm_slock) == 0)
                   3149:                                        continue;
                   3150:
                   3151:                                pte = pv->pv_pte;
                   3152:
                   3153:                                /* Don't steal wired mappings. */
                   3154:                                if (pmap_pte_w(pte)) {
                   3155:                                        simple_unlock(&pvpmap->pm_slock);
                   3156:                                        continue;
                   3157:                                }
                   3158:
                   3159:                                cpu_id = cpu_number();
                   3160:
                   3161:                                /*
                   3162:                                 * Okay!  We have a mapping we can steal;
                   3163:                                 * remove it and grab the pv_entry.
                   3164:                                 */
                   3165:                                if (pmap_remove_mapping(pvpmap, pv->pv_va,
                   3166:                                    pte, FALSE, cpu_id, &prmt))
                   3167:                                        PMAP_SYNC_ISTREAM(pvpmap);
                   3168:
                   3169:                                /* Unlock everything and return. */
                   3170:                                simple_unlock(&pvpmap->pm_slock);
                   3171:                                simple_unlock(&pvh->pvh_slock);
                   3172:                                return (prmt.prmt_pv);
                   3173:                        }
                   3174:                        simple_unlock(&pvh->pvh_slock);
                   3175:                }
                   3176:        }
                   3177:
                   3178:        return (NULL);
                   3179: }
                   3180:
                   3181: /*
                   3182:  * pmap_pv_free:
                   3183:  *
                   3184:  *     Free a pv_entry.
                   3185:  */
                   3186: void
                   3187: pmap_pv_free(struct pv_entry *pv)
                   3188: {
                   3189:
                   3190:        pool_put(&pmap_pv_pool, pv);
                   3191: }
                   3192:
                   3193: /*
                   3194:  * pmap_pv_page_alloc:
                   3195:  *
                   3196:  *     Allocate a page for the pv_entry pool.
                   3197:  */
                   3198: void *
                   3199: pmap_pv_page_alloc(struct pool *pp, int flags)
                   3200: {
                   3201:        paddr_t pg;
                   3202:
                   3203:        if (pmap_physpage_alloc(PGU_PVENT, &pg))
                   3204:                return ((void *)ALPHA_PHYS_TO_K0SEG(pg));
                   3205:        return (NULL);
                   3206: }
                   3207:
                   3208: /*
                   3209:  * pmap_pv_page_free:
                   3210:  *
                   3211:  *     Free a pv_entry pool page.
                   3212:  */
                   3213: void
                   3214: pmap_pv_page_free(struct pool *pp, void *v)
                   3215: {
                   3216:
                   3217:        pmap_physpage_free(ALPHA_K0SEG_TO_PHYS((vaddr_t)v));
                   3218: }
                   3219:
                   3220: /******************** misc. functions ********************/
                   3221:
                   3222: /*
                   3223:  * pmap_physpage_alloc:
                   3224:  *
                   3225:  *     Allocate a single page from the VM system and return the
                   3226:  *     physical address for that page.
                   3227:  */
                   3228: boolean_t
                   3229: pmap_physpage_alloc(int usage, paddr_t *pap)
                   3230: {
                   3231:        struct vm_page *pg;
                   3232:        struct pv_head *pvh;
                   3233:        paddr_t pa;
                   3234:
                   3235:        /*
                   3236:         * Don't ask for a zeroed page in the L1PT case -- we will
                   3237:         * properly initialize it in the constructor.
                   3238:         */
                   3239:
                   3240:        pg = uvm_pagealloc(NULL, 0, NULL, usage == PGU_L1PT ?
                   3241:            UVM_PGA_USERESERVE : UVM_PGA_USERESERVE|UVM_PGA_ZERO);
                   3242:        if (pg != NULL) {
                   3243:                pa = VM_PAGE_TO_PHYS(pg);
                   3244:
                   3245:                pvh = pa_to_pvh(pa);
                   3246:                simple_lock(&pvh->pvh_slock);
                   3247: #ifdef DIAGNOSTIC
                   3248:                if (pvh->pvh_usage != PGU_NORMAL) {
                   3249:                        printf("pmap_physpage_alloc: page 0x%lx is "
                   3250:                            "in use (%s)\n", pa,
                   3251:                            pmap_pgu_strings[pvh->pvh_usage]);
                   3252:                        panic("pmap_physpage_alloc");
                   3253:                }
                   3254:                if (pvh->pvh_refcnt != 0) {
                   3255:                        printf("pmap_physpage_alloc: page 0x%lx has "
                   3256:                            "%d references\n", pa, pvh->pvh_refcnt);
                   3257:                        panic("pmap_physpage_alloc");
                   3258:                }
                   3259: #endif
                   3260:                pvh->pvh_usage = usage;
                   3261:                simple_unlock(&pvh->pvh_slock);
                   3262:                *pap = pa;
                   3263:                return (TRUE);
                   3264:        }
                   3265:        return (FALSE);
                   3266: }
                   3267:
                   3268: /*
                   3269:  * pmap_physpage_free:
                   3270:  *
                   3271:  *     Free the single page table page at the specified physical address.
                   3272:  */
                   3273: void
                   3274: pmap_physpage_free(paddr_t pa)
                   3275: {
                   3276:        struct pv_head *pvh;
                   3277:        struct vm_page *pg;
                   3278:
                   3279:        if ((pg = PHYS_TO_VM_PAGE(pa)) == NULL)
                   3280:                panic("pmap_physpage_free: bogus physical page address");
                   3281:
                   3282:        pvh = pa_to_pvh(pa);
                   3283:
                   3284:        simple_lock(&pvh->pvh_slock);
                   3285: #ifdef DIAGNOSTIC
                   3286:        if (pvh->pvh_usage == PGU_NORMAL)
                   3287:                panic("pmap_physpage_free: not in use?!");
                   3288:        if (pvh->pvh_refcnt != 0)
                   3289:                panic("pmap_physpage_free: page still has references");
                   3290: #endif
                   3291:        pvh->pvh_usage = PGU_NORMAL;
                   3292:        simple_unlock(&pvh->pvh_slock);
                   3293:
                   3294:        uvm_pagefree(pg);
                   3295: }
                   3296:
                   3297: /*
                   3298:  * pmap_physpage_addref:
                   3299:  *
                   3300:  *     Add a reference to the specified special use page.
                   3301:  */
                   3302: int
                   3303: pmap_physpage_addref(void *kva)
                   3304: {
                   3305:        struct pv_head *pvh;
                   3306:        paddr_t pa;
                   3307:        int rval;
                   3308:
                   3309:        pa = ALPHA_K0SEG_TO_PHYS(trunc_page((vaddr_t)kva));
                   3310:        pvh = pa_to_pvh(pa);
                   3311:
                   3312:        simple_lock(&pvh->pvh_slock);
                   3313: #ifdef DIAGNOSTIC
                   3314:        if (pvh->pvh_usage == PGU_NORMAL)
                   3315:                panic("pmap_physpage_addref: not a special use page");
                   3316: #endif
                   3317:
                   3318:        rval = ++pvh->pvh_refcnt;
                   3319:        simple_unlock(&pvh->pvh_slock);
                   3320:
                   3321:        return (rval);
                   3322: }
                   3323:
                   3324: /*
                   3325:  * pmap_physpage_delref:
                   3326:  *
                   3327:  *     Delete a reference to the specified special use page.
                   3328:  */
                   3329: int
                   3330: pmap_physpage_delref(void *kva)
                   3331: {
                   3332:        struct pv_head *pvh;
                   3333:        paddr_t pa;
                   3334:        int rval;
                   3335:
                   3336:        pa = ALPHA_K0SEG_TO_PHYS(trunc_page((vaddr_t)kva));
                   3337:        pvh = pa_to_pvh(pa);
                   3338:
                   3339:        simple_lock(&pvh->pvh_slock);
                   3340: #ifdef DIAGNOSTIC
                   3341:        if (pvh->pvh_usage == PGU_NORMAL)
                   3342:                panic("pmap_physpage_delref: not a special use page");
                   3343: #endif
                   3344:
                   3345:        rval = --pvh->pvh_refcnt;
                   3346:
                   3347: #ifdef DIAGNOSTIC
                   3348:        /*
                   3349:         * Make sure we never have a negative reference count.
                   3350:         */
                   3351:        if (pvh->pvh_refcnt < 0)
                   3352:                panic("pmap_physpage_delref: negative reference count");
                   3353: #endif
                   3354:        simple_unlock(&pvh->pvh_slock);
                   3355:
                   3356:        return (rval);
                   3357: }
                   3358:
                   3359: /******************** page table page management ********************/
                   3360:
                   3361: /*
                   3362:  * pmap_growkernel:            [ INTERFACE ]
                   3363:  *
                   3364:  *     Grow the kernel address space.  This is a hint from the
                   3365:  *     upper layer to pre-allocate more kernel PT pages.
                   3366:  */
                   3367: vaddr_t
                   3368: pmap_growkernel(vaddr_t maxkvaddr)
                   3369: {
                   3370:        struct pmap *kpm = pmap_kernel(), *pm;
                   3371:        paddr_t ptaddr;
                   3372:        pt_entry_t *l1pte, *l2pte, pte;
                   3373:        vaddr_t va;
                   3374:        int s, l1idx;
                   3375:
                   3376:        if (maxkvaddr <= virtual_end)
                   3377:                goto out;               /* we are OK */
                   3378:
                   3379:        s = splhigh();                  /* to be safe */
                   3380:        simple_lock(&pmap_growkernel_slock);
                   3381:
                   3382:        va = virtual_end;
                   3383:
                   3384:        while (va < maxkvaddr) {
                   3385:                /*
                   3386:                 * If there is no valid L1 PTE (i.e. no L2 PT page),
                   3387:                 * allocate a new L2 PT page and insert it into the
                   3388:                 * L1 map.
                   3389:                 */
                   3390:                l1pte = pmap_l1pte(kpm, va);
                   3391:                if (pmap_pte_v(l1pte) == 0) {
                   3392:                        /*
                   3393:                         * XXX PGU_NORMAL?  It's not a "traditional" PT page.
                   3394:                         */
                   3395:                        if (uvm.page_init_done == FALSE) {
                   3396:                                /*
                   3397:                                 * We're growing the kernel pmap early (from
                   3398:                                 * uvm_pageboot_alloc()).  This case must
                   3399:                                 * be handled a little differently.
                   3400:                                 */
                   3401:                                ptaddr = ALPHA_K0SEG_TO_PHYS(
                   3402:                                    pmap_steal_memory(PAGE_SIZE, NULL, NULL));
                   3403:                        } else if (pmap_physpage_alloc(PGU_NORMAL,
                   3404:                                   &ptaddr) == FALSE)
                   3405:                                goto die;
                   3406:                        pte = (atop(ptaddr) << PG_SHIFT) |
                   3407:                            PG_V | PG_ASM | PG_KRE | PG_KWE | PG_WIRED;
                   3408:                        *l1pte = pte;
                   3409:
                   3410:                        l1idx = l1pte_index(va);
                   3411:
                   3412:                        /* Update all the user pmaps. */
                   3413:                        simple_lock(&pmap_all_pmaps_slock);
                   3414:                        for (pm = TAILQ_FIRST(&pmap_all_pmaps);
                   3415:                             pm != NULL; pm = TAILQ_NEXT(pm, pm_list)) {
                   3416:                                /* Skip the kernel pmap. */
                   3417:                                if (pm == pmap_kernel())
                   3418:                                        continue;
                   3419:
                   3420:                                PMAP_LOCK(pm);
                   3421:                                if (pm->pm_lev1map == kernel_lev1map) {
                   3422:                                        PMAP_UNLOCK(pm);
                   3423:                                        continue;
                   3424:                                }
                   3425:                                pm->pm_lev1map[l1idx] = pte;
                   3426:                                PMAP_UNLOCK(pm);
                   3427:                        }
                   3428:                        simple_unlock(&pmap_all_pmaps_slock);
                   3429:                }
                   3430:
                   3431:                /*
                   3432:                 * Have an L2 PT page now, add the L3 PT page.
                   3433:                 */
                   3434:                l2pte = pmap_l2pte(kpm, va, l1pte);
                   3435:                KASSERT(pmap_pte_v(l2pte) == 0);
                   3436:                if (uvm.page_init_done == FALSE) {
                   3437:                        /*
                   3438:                         * See above.
                   3439:                         */
                   3440:                        ptaddr = ALPHA_K0SEG_TO_PHYS(
                   3441:                            pmap_steal_memory(PAGE_SIZE, NULL, NULL));
                   3442:                } else if (pmap_physpage_alloc(PGU_NORMAL, &ptaddr) == FALSE)
                   3443:                        goto die;
                   3444:                *l2pte = (atop(ptaddr) << PG_SHIFT) |
                   3445:                    PG_V | PG_ASM | PG_KRE | PG_KWE | PG_WIRED;
                   3446:                va += ALPHA_L2SEG_SIZE;
                   3447:        }
                   3448:
                   3449:        /* Invalidate the L1 PT cache. */
                   3450:        pool_cache_invalidate(&pmap_l1pt_cache);
                   3451:
                   3452:        virtual_end = va;
                   3453:
                   3454:        simple_unlock(&pmap_growkernel_slock);
                   3455:        splx(s);
                   3456:
                   3457:  out:
                   3458:        return (virtual_end);
                   3459:
                   3460:  die:
                   3461:        panic("pmap_growkernel: out of memory");
                   3462: }
                   3463:
                   3464: /*
                   3465:  * pmap_lev1map_create:
                   3466:  *
                   3467:  *     Create a new level 1 page table for the specified pmap.
                   3468:  *
                   3469:  *     Note: the pmap must already be locked.
                   3470:  */
                   3471: int
                   3472: pmap_lev1map_create(pmap_t pmap, cpuid_t cpu_id)
                   3473: {
                   3474:        pt_entry_t *l1pt;
                   3475:
                   3476: #ifdef DIAGNOSTIC
                   3477:        if (pmap == pmap_kernel())
                   3478:                panic("pmap_lev1map_create: got kernel pmap");
                   3479:
                   3480:        if (pmap->pm_asn[cpu_id] != PMAP_ASN_RESERVED)
                   3481:                panic("pmap_lev1map_create: pmap uses non-reserved ASN");
                   3482: #endif
                   3483:
                   3484:        simple_lock(&pmap_growkernel_slock);
                   3485:
                   3486:        l1pt = pool_cache_get(&pmap_l1pt_cache, PR_NOWAIT);
                   3487:        if (l1pt == NULL) {
                   3488:                simple_unlock(&pmap_growkernel_slock);
                   3489:                return (ENOMEM);
                   3490:        }
                   3491:
                   3492:        pmap->pm_lev1map = l1pt;
                   3493:
                   3494:        simple_unlock(&pmap_growkernel_slock);
                   3495:
                   3496:        /*
                   3497:         * The page table base has changed; if the pmap was active,
                   3498:         * reactivate it.
                   3499:         */
                   3500:        if (PMAP_ISACTIVE(pmap, cpu_id)) {
                   3501:                pmap_asn_alloc(pmap, cpu_id);
                   3502:                PMAP_ACTIVATE(pmap, curproc, cpu_id);
                   3503:        }
                   3504:        return (0);
                   3505: }
                   3506:
                   3507: /*
                   3508:  * pmap_lev1map_destroy:
                   3509:  *
                   3510:  *     Destroy the level 1 page table for the specified pmap.
                   3511:  *
                   3512:  *     Note: the pmap must already be locked.
                   3513:  */
                   3514: void
                   3515: pmap_lev1map_destroy(pmap_t pmap, cpuid_t cpu_id)
                   3516: {
                   3517:        pt_entry_t *l1pt = pmap->pm_lev1map;
                   3518:
                   3519: #ifdef DIAGNOSTIC
                   3520:        if (pmap == pmap_kernel())
                   3521:                panic("pmap_lev1map_destroy: got kernel pmap");
                   3522: #endif
                   3523:
                   3524:        /*
                   3525:         * Go back to referencing the global kernel_lev1map.
                   3526:         */
                   3527:        pmap->pm_lev1map = kernel_lev1map;
                   3528:
                   3529:        /*
                   3530:         * The page table base has changed; if the pmap was active,
                   3531:         * reactivate it.  Note that allocation of a new ASN is
                   3532:         * not necessary here:
                   3533:         *
                   3534:         *      (1) We've gotten here because we've deleted all
                   3535:         *          user mappings in the pmap, invalidating the
                   3536:         *          TLB entries for them as we go.
                   3537:         *
                   3538:         *      (2) kernel_lev1map contains only kernel mappings, which
                   3539:         *          were identical in the user pmap, and all of
                   3540:         *          those mappings have PG_ASM, so the ASN doesn't
                   3541:         *          matter.
                   3542:         *
                   3543:         * We do, however, ensure that the pmap is using the
                   3544:         * reserved ASN, to ensure that no two pmaps never have
                   3545:         * clashing TLB entries.
                   3546:         */
                   3547:        PMAP_INVALIDATE_ASN(pmap, cpu_id);
                   3548:        if (PMAP_ISACTIVE(pmap, cpu_id))
                   3549:                PMAP_ACTIVATE(pmap, curproc, cpu_id);
                   3550:
                   3551:        /*
                   3552:         * Free the old level 1 page table page.
                   3553:         */
                   3554:        pool_cache_put(&pmap_l1pt_cache, l1pt);
                   3555: }
                   3556:
                   3557: /*
                   3558:  * pmap_l1pt_ctor:
                   3559:  *
                   3560:  *     Pool cache constructor for L1 PT pages.
                   3561:  */
                   3562: int
                   3563: pmap_l1pt_ctor(void *arg, void *object, int flags)
                   3564: {
                   3565:        pt_entry_t *l1pt = object, pte;
                   3566:        int i;
                   3567:
                   3568:        /*
                   3569:         * Initialize the new level 1 table by zeroing the
                   3570:         * user portion and copying the kernel mappings into
                   3571:         * the kernel portion.
                   3572:         */
                   3573:        for (i = 0; i < l1pte_index(VM_MIN_KERNEL_ADDRESS); i++)
                   3574:                l1pt[i] = 0;
                   3575:
                   3576:        for (i = l1pte_index(VM_MIN_KERNEL_ADDRESS);
                   3577:             i <= l1pte_index(VM_MAX_KERNEL_ADDRESS); i++)
                   3578:                l1pt[i] = kernel_lev1map[i];
                   3579:
                   3580:        /*
                   3581:         * Now, map the new virtual page table.  NOTE: NO ASM!
                   3582:         */
                   3583:        pte = ((ALPHA_K0SEG_TO_PHYS((vaddr_t) l1pt) >> PGSHIFT) << PG_SHIFT) |
                   3584:            PG_V | PG_KRE | PG_KWE;
                   3585:        l1pt[l1pte_index(VPTBASE)] = pte;
                   3586:
                   3587:        return (0);
                   3588: }
                   3589:
                   3590: /*
                   3591:  * pmap_l1pt_alloc:
                   3592:  *
                   3593:  *     Page allocator for L1 PT pages.
                   3594:  */
                   3595: void *
                   3596: pmap_l1pt_alloc(struct pool *pp, int flags)
                   3597: {
                   3598:        paddr_t ptpa;
                   3599:
                   3600:        /*
                   3601:         * Attempt to allocate a free page.
                   3602:         */
                   3603:        if (pmap_physpage_alloc(PGU_L1PT, &ptpa) == FALSE) {
                   3604: #if 0
                   3605:                /*
                   3606:                 * Yow!  No free pages!  Try to steal a PT page from
                   3607:                 * another pmap!
                   3608:                 */
                   3609:                if (pmap_ptpage_steal(pmap, PGU_L1PT, &ptpa) == FALSE)
                   3610: #endif
                   3611:                        return (NULL);
                   3612:        }
                   3613:
                   3614:        return ((void *) ALPHA_PHYS_TO_K0SEG(ptpa));
                   3615: }
                   3616:
                   3617: /*
                   3618:  * pmap_l1pt_free:
                   3619:  *
                   3620:  *     Page freer for L1 PT pages.
                   3621:  */
                   3622: void
                   3623: pmap_l1pt_free(struct pool *pp, void *v)
                   3624: {
                   3625:
                   3626:        pmap_physpage_free(ALPHA_K0SEG_TO_PHYS((vaddr_t) v));
                   3627: }
                   3628:
                   3629: /*
                   3630:  * pmap_ptpage_alloc:
                   3631:  *
                   3632:  *     Allocate a level 2 or level 3 page table page, and
                   3633:  *     initialize the PTE that references it.
                   3634:  *
                   3635:  *     Note: the pmap must already be locked.
                   3636:  */
                   3637: int
                   3638: pmap_ptpage_alloc(pmap_t pmap, pt_entry_t *pte, int usage)
                   3639: {
                   3640:        paddr_t ptpa;
                   3641:
                   3642:        /*
                   3643:         * Allocate the page table page.
                   3644:         */
                   3645:        if (pmap_physpage_alloc(usage, &ptpa) == FALSE) {
                   3646:                /*
                   3647:                 * Yow!  No free pages!  Try to steal a PT page from
                   3648:                 * another pmap!
                   3649:                 */
                   3650:                if (pmap_ptpage_steal(pmap, usage, &ptpa) == FALSE)
                   3651:                        return (ENOMEM);
                   3652:        }
                   3653:
                   3654:        /*
                   3655:         * Initialize the referencing PTE.
                   3656:         */
                   3657:        PMAP_SET_PTE(pte, ((ptpa >> PGSHIFT) << PG_SHIFT) |
                   3658:            PG_V | PG_KRE | PG_KWE | PG_WIRED |
                   3659:            (pmap == pmap_kernel() ? PG_ASM : 0));
                   3660:
                   3661:        return (0);
                   3662: }
                   3663:
                   3664: /*
                   3665:  * pmap_ptpage_free:
                   3666:  *
                   3667:  *     Free the level 2 or level 3 page table page referenced
                   3668:  *     be the provided PTE.
                   3669:  *
                   3670:  *     Note: the pmap must already be locked.
                   3671:  */
                   3672: void
                   3673: pmap_ptpage_free(pmap_t pmap, pt_entry_t *pte, pt_entry_t **ptp)
                   3674: {
                   3675:        paddr_t ptpa;
                   3676:
                   3677:        /*
                   3678:         * Extract the physical address of the page from the PTE
                   3679:         * and clear the entry.
                   3680:         */
                   3681:        ptpa = pmap_pte_pa(pte);
                   3682:        PMAP_SET_PTE(pte, PG_NV);
                   3683:
                   3684:        /*
                   3685:         * Check to see if we're stealing the PT page.  If we are,
                   3686:         * zero it, and return the KSEG address of the page.
                   3687:         */
                   3688:        if (ptp != NULL) {
                   3689:                pmap_zero_page(PHYS_TO_VM_PAGE(ptpa));
                   3690:                *ptp = (pt_entry_t *)ALPHA_PHYS_TO_K0SEG(ptpa);
                   3691:        } else {
                   3692: #ifdef DEBUG
                   3693:                pmap_zero_page(PHYS_TO_VM_PAGE(ptpa));
                   3694: #endif
                   3695:                pmap_physpage_free(ptpa);
                   3696:        }
                   3697: }
                   3698:
                   3699: /*
                   3700:  * pmap_ptpage_steal:
                   3701:  *
                   3702:  *     Steal a PT page from a pmap.
                   3703:  */
                   3704: boolean_t
                   3705: pmap_ptpage_steal(pmap_t pmap, int usage, paddr_t *pap)
                   3706: {
                   3707:        struct pv_head *pvh;
                   3708:        pmap_t spmap;
                   3709:        int l1idx, l2idx, l3idx;
                   3710:        pt_entry_t *lev2map, *lev3map;
                   3711:        vaddr_t va;
                   3712:        paddr_t pa;
                   3713:        struct prm_thief prmt;
                   3714:        cpuid_t cpu_id = cpu_number();
                   3715:        boolean_t needisync = FALSE;
                   3716:
                   3717:        prmt.prmt_flags = PRMT_PTP;
                   3718:        prmt.prmt_ptp = NULL;
                   3719:
                   3720:        /*
                   3721:         * We look for pmaps which do not reference kernel_lev1map (which
                   3722:         * would indicate that they are either the kernel pmap, or a user
                   3723:         * pmap with no valid mappings).  Since the list of all pmaps is
                   3724:         * maintained in an LRU fashion, we should get a pmap that is
                   3725:         * `more inactive' than our current pmap (although this may not
                   3726:         * always be the case).
                   3727:         *
                   3728:         * We start looking for valid L1 PTEs at the lowest address,
                   3729:         * go to that L2, look for the first valid L2 PTE, and steal
                   3730:         * that L3 PT page.
                   3731:         */
                   3732:        simple_lock(&pmap_all_pmaps_slock);
                   3733:        for (spmap = TAILQ_FIRST(&pmap_all_pmaps);
                   3734:             spmap != NULL; spmap = TAILQ_NEXT(spmap, pm_list)) {
                   3735:                /*
                   3736:                 * Skip the kernel pmap and ourselves.
                   3737:                 */
                   3738:                if (spmap == pmap_kernel() || spmap == pmap)
                   3739:                        continue;
                   3740:
                   3741:                PMAP_LOCK(spmap);
                   3742:                if (spmap->pm_lev1map == kernel_lev1map) {
                   3743:                        PMAP_UNLOCK(spmap);
                   3744:                        continue;
                   3745:                }
                   3746:
                   3747:                /*
                   3748:                 * Have a candidate pmap.  Loop through the PT pages looking
                   3749:                 * for one we can steal.
                   3750:                 */
                   3751:                for (l1idx = 0;
                   3752:                     l1idx < l1pte_index(VM_MAXUSER_ADDRESS); l1idx++) {
                   3753:                        if (pmap_pte_v(&spmap->pm_lev1map[l1idx]) == 0)
                   3754:                                continue;
                   3755:
                   3756:                        lev2map = (pt_entry_t *)ALPHA_PHYS_TO_K0SEG(
                   3757:                            pmap_pte_pa(&spmap->pm_lev1map[l1idx]));
                   3758:                        for (l2idx = 0; l2idx < NPTEPG; l2idx++) {
                   3759:                                if (pmap_pte_v(&lev2map[l2idx]) == 0)
                   3760:                                        continue;
                   3761:                                lev3map = (pt_entry_t *)ALPHA_PHYS_TO_K0SEG(
                   3762:                                    pmap_pte_pa(&lev2map[l2idx]));
                   3763:                                for (l3idx = 0; l3idx < NPTEPG; l3idx++) {
                   3764:                                        /*
                   3765:                                         * If the entry is valid and wired,
                   3766:                                         * we cannot steal this page.
                   3767:                                         */
                   3768:                                        if (pmap_pte_v(&lev3map[l3idx]) &&
                   3769:                                            pmap_pte_w(&lev3map[l3idx]))
                   3770:                                                break;
                   3771:                                }
                   3772:
                   3773:                                /*
                   3774:                                 * If we scanned all of the current L3 table
                   3775:                                 * without finding a wired entry, we can
                   3776:                                 * steal this page!
                   3777:                                 */
                   3778:                                if (l3idx == NPTEPG)
                   3779:                                        goto found_one;
                   3780:                        }
                   3781:                }
                   3782:
                   3783:                /*
                   3784:                 * Didn't find something we could steal in this
                   3785:                 * pmap, try the next one.
                   3786:                 */
                   3787:                PMAP_UNLOCK(spmap);
                   3788:                continue;
                   3789:
                   3790:  found_one:
                   3791:                /* ...don't need this anymore. */
                   3792:                simple_unlock(&pmap_all_pmaps_slock);
                   3793:
                   3794:                /*
                   3795:                 * Okay!  We have a PT page we can steal.  l1idx and
                   3796:                 * l2idx indicate which L1 PTP and L2 PTP we should
                   3797:                 * use to compute the virtual addresses the L3 PTP
                   3798:                 * maps.  Loop through all the L3 PTEs in this range
                   3799:                 * and nuke the mappings for them.  When we're through,
                   3800:                 * we'll have a PT page pointed to by prmt.prmt_ptp!
                   3801:                 */
                   3802:                for (l3idx = 0,
                   3803:                     va = (l1idx * ALPHA_L1SEG_SIZE) +
                   3804:                          (l2idx * ALPHA_L2SEG_SIZE);
                   3805:                     l3idx < NPTEPG && prmt.prmt_ptp == NULL;
                   3806:                     l3idx++, va += PAGE_SIZE) {
                   3807:                        if (pmap_pte_v(&lev3map[l3idx])) {
                   3808:                                needisync |= pmap_remove_mapping(spmap, va,
                   3809:                                    &lev3map[l3idx], TRUE, cpu_id, &prmt);
                   3810:                        }
                   3811:                }
                   3812:
                   3813:                if (needisync)
                   3814:                        PMAP_SYNC_ISTREAM(pmap);
                   3815:
                   3816:                PMAP_UNLOCK(spmap);
                   3817:
                   3818: #ifdef DIAGNOSTIC
                   3819:                if (prmt.prmt_ptp == NULL)
                   3820:                        panic("pmap_ptptage_steal: failed");
                   3821:                if (prmt.prmt_ptp != lev3map)
                   3822:                        panic("pmap_ptpage_steal: inconsistent");
                   3823: #endif
                   3824:                pa = ALPHA_K0SEG_TO_PHYS((vaddr_t)prmt.prmt_ptp);
                   3825:
                   3826:                /*
                   3827:                 * Don't bother locking here; the assignment is atomic.
                   3828:                 */
                   3829:                pvh = pa_to_pvh(pa);
                   3830:                pvh->pvh_usage = usage;
                   3831:
                   3832:                *pap = pa;
                   3833:                return (TRUE);
                   3834:        }
                   3835:        simple_unlock(&pmap_all_pmaps_slock);
                   3836:        return (FALSE);
                   3837: }
                   3838:
                   3839: /*
                   3840:  * pmap_l3pt_delref:
                   3841:  *
                   3842:  *     Delete a reference on a level 3 PT page.  If the reference drops
                   3843:  *     to zero, free it.
                   3844:  *
                   3845:  *     Note: the pmap must already be locked.
                   3846:  */
                   3847: void
                   3848: pmap_l3pt_delref(pmap_t pmap, vaddr_t va, pt_entry_t *l3pte, cpuid_t cpu_id,
                   3849:     pt_entry_t **ptp)
                   3850: {
                   3851:        pt_entry_t *l1pte, *l2pte;
                   3852:
                   3853:        l1pte = pmap_l1pte(pmap, va);
                   3854:        l2pte = pmap_l2pte(pmap, va, l1pte);
                   3855:
                   3856: #ifdef DIAGNOSTIC
                   3857:        if (pmap == pmap_kernel())
                   3858:                panic("pmap_l3pt_delref: kernel pmap");
                   3859: #endif
                   3860:
                   3861:        if (pmap_physpage_delref(l3pte) == 0) {
                   3862:                /*
                   3863:                 * No more mappings; we can free the level 3 table.
                   3864:                 */
                   3865: #ifdef DEBUG
                   3866:                if (pmapdebug & PDB_PTPAGE)
                   3867:                        printf("pmap_l3pt_delref: freeing level 3 table at "
                   3868:                            "0x%lx\n", pmap_pte_pa(l2pte));
                   3869: #endif
                   3870:                pmap_ptpage_free(pmap, l2pte, ptp);
                   3871:                pmap->pm_nlev3--;
                   3872:
                   3873:                /*
                   3874:                 * We've freed a level 3 table, so we must
                   3875:                 * invalidate the TLB entry for that PT page
                   3876:                 * in the Virtual Page Table VA range, because
                   3877:                 * otherwise the PALcode will service a TLB
                   3878:                 * miss using the stale VPT TLB entry it entered
                   3879:                 * behind our back to shortcut to the VA's PTE.
                   3880:                 */
                   3881:                PMAP_INVALIDATE_TLB(pmap,
                   3882:                    (vaddr_t)(&VPT[VPT_INDEX(va)]), FALSE,
                   3883:                    PMAP_ISACTIVE(pmap, cpu_id), cpu_id);
                   3884:                PMAP_TLB_SHOOTDOWN(pmap,
                   3885:                    (vaddr_t)(&VPT[VPT_INDEX(va)]), 0);
                   3886:
                   3887:                /*
                   3888:                 * We've freed a level 3 table, so delete the reference
                   3889:                 * on the level 2 table.
                   3890:                 */
                   3891:                pmap_l2pt_delref(pmap, l1pte, l2pte, cpu_id);
                   3892:        }
                   3893: }
                   3894:
                   3895: /*
                   3896:  * pmap_l2pt_delref:
                   3897:  *
                   3898:  *     Delete a reference on a level 2 PT page.  If the reference drops
                   3899:  *     to zero, free it.
                   3900:  *
                   3901:  *     Note: the pmap must already be locked.
                   3902:  */
                   3903: void
                   3904: pmap_l2pt_delref(pmap_t pmap, pt_entry_t *l1pte, pt_entry_t *l2pte,
                   3905:     cpuid_t cpu_id)
                   3906: {
                   3907:
                   3908: #ifdef DIAGNOSTIC
                   3909:        if (pmap == pmap_kernel())
                   3910:                panic("pmap_l2pt_delref: kernel pmap");
                   3911: #endif
                   3912:
                   3913:        if (pmap_physpage_delref(l2pte) == 0) {
                   3914:                /*
                   3915:                 * No more mappings in this segment; we can free the
                   3916:                 * level 2 table.
                   3917:                 */
                   3918: #ifdef DEBUG
                   3919:                if (pmapdebug & PDB_PTPAGE)
                   3920:                        printf("pmap_l2pt_delref: freeing level 2 table at "
                   3921:                            "0x%lx\n", pmap_pte_pa(l1pte));
                   3922: #endif
                   3923:                pmap_ptpage_free(pmap, l1pte, NULL);
                   3924:                pmap->pm_nlev2--;
                   3925:
                   3926:                /*
                   3927:                 * We've freed a level 2 table, so delete the reference
                   3928:                 * on the level 1 table.
                   3929:                 */
                   3930:                pmap_l1pt_delref(pmap, l1pte, cpu_id);
                   3931:        }
                   3932: }
                   3933:
                   3934: /*
                   3935:  * pmap_l1pt_delref:
                   3936:  *
                   3937:  *     Delete a reference on a level 1 PT page.  If the reference drops
                   3938:  *     to zero, free it.
                   3939:  *
                   3940:  *     Note: the pmap must already be locked.
                   3941:  */
                   3942: void
                   3943: pmap_l1pt_delref(pmap_t pmap, pt_entry_t *l1pte, cpuid_t cpu_id)
                   3944: {
                   3945:
                   3946: #ifdef DIAGNOSTIC
                   3947:        if (pmap == pmap_kernel())
                   3948:                panic("pmap_l1pt_delref: kernel pmap");
                   3949: #endif
                   3950:
                   3951:        if (pmap_physpage_delref(l1pte) == 0) {
                   3952:                /*
                   3953:                 * No more level 2 tables left, go back to the global
                   3954:                 * kernel_lev1map.
                   3955:                 */
                   3956:                pmap_lev1map_destroy(pmap, cpu_id);
                   3957:        }
                   3958: }
                   3959:
                   3960: /******************** Address Space Number management ********************/
                   3961:
                   3962: /*
                   3963:  * pmap_asn_alloc:
                   3964:  *
                   3965:  *     Allocate and assign an ASN to the specified pmap.
                   3966:  *
                   3967:  *     Note: the pmap must already be locked.
                   3968:  */
                   3969: void
                   3970: pmap_asn_alloc(pmap_t pmap, cpuid_t cpu_id)
                   3971: {
                   3972:
                   3973: #ifdef DEBUG
                   3974:        if (pmapdebug & (PDB_FOLLOW|PDB_ASN))
                   3975:                printf("pmap_asn_alloc(%p)\n", pmap);
                   3976: #endif
                   3977:
                   3978:        /*
                   3979:         * If the pmap is still using the global kernel_lev1map, there
                   3980:         * is no need to assign an ASN at this time, because only
                   3981:         * kernel mappings exist in that map, and all kernel mappings
                   3982:         * have PG_ASM set.  If the pmap eventually gets its own
                   3983:         * lev1map, an ASN will be allocated at that time.
                   3984:         */
                   3985:        if (pmap->pm_lev1map == kernel_lev1map) {
                   3986: #ifdef DEBUG
                   3987:                if (pmapdebug & PDB_ASN)
                   3988:                        printf("pmap_asn_alloc: still references "
                   3989:                            "kernel_lev1map\n");
                   3990: #endif
                   3991: #ifdef DIAGNOSTIC
                   3992:                if (pmap->pm_asn[cpu_id] != PMAP_ASN_RESERVED)
                   3993:                        panic("pmap_asn_alloc: kernel_lev1map without "
                   3994:                            "PMAP_ASN_RESERVED");
                   3995: #endif
                   3996:                return;
                   3997:        }
                   3998:
                   3999:        /*
                   4000:         * On processors which do not implement ASNs, the swpctx PALcode
                   4001:         * operation will automatically invalidate the TLB and I-cache,
                   4002:         * so we don't need to do that here.
                   4003:         */
                   4004:        if (pmap_max_asn == 0) {
                   4005:                /*
                   4006:                 * Refresh the pmap's generation number, to
                   4007:                 * simplify logic elsewhere.
                   4008:                 */
                   4009:                pmap->pm_asngen[cpu_id] = pmap_asn_generation[cpu_id];
                   4010: #ifdef DEBUG
                   4011:                if (pmapdebug & PDB_ASN)
                   4012:                        printf("pmap_asn_alloc: no ASNs, using asngen %lu\n",
                   4013:                            pmap->pm_asngen[cpu_id]);
                   4014: #endif
                   4015:                return;
                   4016:        }
                   4017:
                   4018:        /*
                   4019:         * Hopefully, we can continue using the one we have...
                   4020:         */
                   4021:        if (pmap->pm_asn[cpu_id] != PMAP_ASN_RESERVED &&
                   4022:            pmap->pm_asngen[cpu_id] == pmap_asn_generation[cpu_id]) {
                   4023:                /*
                   4024:                 * ASN is still in the current generation; keep on using it.
                   4025:                 */
                   4026: #ifdef DEBUG
                   4027:                if (pmapdebug & PDB_ASN)
                   4028:                        printf("pmap_asn_alloc: same generation, keeping %u\n",
                   4029:                            pmap->pm_asn[cpu_id]);
                   4030: #endif
                   4031:                return;
                   4032:        }
                   4033:
                   4034:        /*
                   4035:         * Need to assign a new ASN.  Grab the next one, incrementing
                   4036:         * the generation number if we have to.
                   4037:         */
                   4038:        if (pmap_next_asn[cpu_id] > pmap_max_asn) {
                   4039:                /*
                   4040:                 * Invalidate all non-PG_ASM TLB entries and the
                   4041:                 * I-cache, and bump the generation number.
                   4042:                 */
                   4043:                ALPHA_TBIAP();
                   4044:                alpha_pal_imb();
                   4045:
                   4046:                pmap_next_asn[cpu_id] = 1;
                   4047:
                   4048:                pmap_asn_generation[cpu_id]++;
                   4049: #ifdef DIAGNOSTIC
                   4050:                if (pmap_asn_generation[cpu_id] == 0) {
                   4051:                        /*
                   4052:                         * The generation number has wrapped.  We could
                   4053:                         * handle this scenario by traversing all of
                   4054:                         * the pmaps, and invalidating the generation
                   4055:                         * number on those which are not currently
                   4056:                         * in use by this processor.
                   4057:                         *
                   4058:                         * However... considering that we're using
                   4059:                         * an unsigned 64-bit integer for generation
                   4060:                         * numbers, on non-ASN CPUs, we won't wrap
                   4061:                         * for approx. 585 million years, or 75 billion
                   4062:                         * years on a 128-ASN CPU (assuming 1000 switch
                   4063:                         * operations per second).
                   4064:                         *
                   4065:                         * So, we don't bother.
                   4066:                         */
                   4067:                        panic("pmap_asn_alloc: too much uptime");
                   4068:                }
                   4069: #endif
                   4070: #ifdef DEBUG
                   4071:                if (pmapdebug & PDB_ASN)
                   4072:                        printf("pmap_asn_alloc: generation bumped to %lu\n",
                   4073:                            pmap_asn_generation[cpu_id]);
                   4074: #endif
                   4075:        }
                   4076:
                   4077:        /*
                   4078:         * Assign the new ASN and validate the generation number.
                   4079:         */
                   4080:        pmap->pm_asn[cpu_id] = pmap_next_asn[cpu_id]++;
                   4081:        pmap->pm_asngen[cpu_id] = pmap_asn_generation[cpu_id];
                   4082:
                   4083: #ifdef DEBUG
                   4084:        if (pmapdebug & PDB_ASN)
                   4085:                printf("pmap_asn_alloc: assigning %u to pmap %p\n",
                   4086:                    pmap->pm_asn[cpu_id], pmap);
                   4087: #endif
                   4088:
                   4089:        /*
                   4090:         * Have a new ASN, so there's no need to sync the I-stream
                   4091:         * on the way back out to userspace.
                   4092:         */
                   4093:        atomic_clearbits_ulong(&pmap->pm_needisync, (1UL << cpu_id));
                   4094: }
                   4095:
                   4096: #if defined(MULTIPROCESSOR)
                   4097: /******************** TLB shootdown code ********************/
                   4098:
                   4099: /*
                   4100:  * pmap_tlb_shootdown:
                   4101:  *
                   4102:  *     Cause the TLB entry for pmap/va to be shot down.
                   4103:  */
                   4104: void
                   4105: pmap_tlb_shootdown(pmap_t pmap, vaddr_t va, pt_entry_t pte)
                   4106: {
                   4107:        u_long ipinum;
                   4108:        cpuid_t i, cpu_id = cpu_number();
                   4109:        struct pmap_tlb_shootdown_q *pq;
                   4110:        struct pmap_tlb_shootdown_job *pj;
                   4111:        int s;
                   4112:
                   4113:        for (i = 0; i < hwrpb->rpb_pcs_cnt; i++) {
                   4114:                if (i == cpu_id || (cpus_running & (1UL << i)) == 0)
                   4115:                        continue;
                   4116:
                   4117:                pq = &pmap_tlb_shootdown_q[i];
                   4118:
                   4119:                PSJQ_LOCK(pq, s);
                   4120:
                   4121:                pj = pmap_tlb_shootdown_job_get(pq);
                   4122:                pq->pq_pte |= pte;
                   4123:                if (pj == NULL) {
                   4124:                        /*
                   4125:                         * Couldn't allocate a job entry.  Just do a
                   4126:                         * TBIA[P].
                   4127:                         */
                   4128:                        if (pq->pq_pte & PG_ASM)
                   4129:                                ipinum = ALPHA_IPI_SHOOTDOWN;
                   4130:                        else
                   4131:                                ipinum = ALPHA_IPI_IMB;
                   4132:                        alpha_send_ipi(i, ipinum);
                   4133:                } else {
                   4134:                        pj->pj_pmap = pmap;
                   4135:                        pj->pj_va = va;
                   4136:                        pj->pj_pte = pte;
                   4137:                        TAILQ_INSERT_TAIL(&pq->pq_head, pj, pj_list);
                   4138:                        ipinum = ALPHA_IPI_SHOOTDOWN;
                   4139:                }
                   4140:
                   4141:                alpha_send_ipi(i, ipinum);
                   4142:
                   4143:                PSJQ_UNLOCK(pq, s);
                   4144:        }
                   4145: }
                   4146:
                   4147: /*
                   4148:  * pmap_do_tlb_shootdown:
                   4149:  *
                   4150:  *     Process pending TLB shootdown operations for this processor.
                   4151:  */
                   4152: void
                   4153: pmap_do_tlb_shootdown(struct cpu_info *ci, struct trapframe *framep)
                   4154: {
                   4155:        cpuid_t cpu_id = ci->ci_cpuid;
                   4156:        u_long cpu_mask = (1UL << cpu_id);
                   4157:        struct pmap_tlb_shootdown_q *pq = &pmap_tlb_shootdown_q[cpu_id];
                   4158:        struct pmap_tlb_shootdown_job *pj;
                   4159:        int s;
                   4160:
                   4161:        PSJQ_LOCK(pq, s);
                   4162:
                   4163:        while ((pj = TAILQ_FIRST(&pq->pq_head)) != NULL) {
                   4164:                TAILQ_REMOVE(&pq->pq_head, pj, pj_list);
                   4165:                PMAP_INVALIDATE_TLB(pj->pj_pmap, pj->pj_va,
                   4166:                    pj->pj_pte & PG_ASM, pj->pj_pmap->pm_cpus & cpu_mask,
                   4167:                    cpu_id);
                   4168:                pmap_tlb_shootdown_job_put(pq, pj);
                   4169:        }
                   4170:        pq->pq_pte = 0;
                   4171:
                   4172:        PSJQ_UNLOCK(pq, s);
                   4173: }
                   4174:
                   4175: /*
                   4176:  * pmap_tlb_shootdown_q_drain:
                   4177:  *
                   4178:  *     Drain a processor's TLB shootdown queue.  We do not perform
                   4179:  *     the shootdown operations.  This is merely a convenience
                   4180:  *     function.
                   4181:  */
                   4182: void
                   4183: pmap_tlb_shootdown_q_drain(cpuid_t cpu_id, boolean_t all)
                   4184: {
                   4185:        struct pmap_tlb_shootdown_q *pq = &pmap_tlb_shootdown_q[cpu_id];
                   4186:        struct pmap_tlb_shootdown_job *pj, *npj;
                   4187:        pt_entry_t npte = 0;
                   4188:        int s;
                   4189:
                   4190:        PSJQ_LOCK(pq, s);
                   4191:
                   4192:        for (pj = TAILQ_FIRST(&pq->pq_head); pj != NULL; pj = npj) {
                   4193:                npj = TAILQ_NEXT(pj, pj_list);
                   4194:                if (all || (pj->pj_pte & PG_ASM) == 0) {
                   4195:                        TAILQ_REMOVE(&pq->pq_head, pj, pj_list);
                   4196:                        pmap_tlb_shootdown_job_put(pq, pj);
                   4197:                } else
                   4198:                        npte |= pj->pj_pte;
                   4199:        }
                   4200:        pq->pq_pte = npte;
                   4201:
                   4202:        PSJQ_UNLOCK(pq, s);
                   4203: }
                   4204:
                   4205: /*
                   4206:  * pmap_tlb_shootdown_job_get:
                   4207:  *
                   4208:  *     Get a TLB shootdown job queue entry.  This places a limit on
                   4209:  *     the number of outstanding jobs a processor may have.
                   4210:  *
                   4211:  *     Note: We expect the queue to be locked.
                   4212:  */
                   4213: struct pmap_tlb_shootdown_job *
                   4214: pmap_tlb_shootdown_job_get(struct pmap_tlb_shootdown_q *pq)
                   4215: {
                   4216:        struct pmap_tlb_shootdown_job *pj;
                   4217:
                   4218:        if (pq->pq_count >= PMAP_TLB_SHOOTDOWN_MAXJOBS)
                   4219:                return (NULL);
                   4220:        pj = pool_get(&pmap_tlb_shootdown_job_pool, PR_NOWAIT);
                   4221:        if (pj != NULL)
                   4222:                pq->pq_count++;
                   4223:        return (pj);
                   4224: }
                   4225:
                   4226: /*
                   4227:  * pmap_tlb_shootdown_job_put:
                   4228:  *
                   4229:  *     Put a TLB shootdown job queue entry onto the free list.
                   4230:  *
                   4231:  *     Note: We expect the queue to be locked.
                   4232:  */
                   4233: void
                   4234: pmap_tlb_shootdown_job_put(struct pmap_tlb_shootdown_q *pq,
                   4235:     struct pmap_tlb_shootdown_job *pj)
                   4236: {
                   4237:
                   4238: #ifdef DIAGNOSTIC
                   4239:        if (pq->pq_count == 0)
                   4240:                panic("pmap_tlb_shootdown_job_put: queue length inconsistency");
                   4241: #endif
                   4242:        pool_put(&pmap_tlb_shootdown_job_pool, pj);
                   4243:        pq->pq_count--;
                   4244: }
                   4245: #endif /* MULTIPROCESSOR */

CVSweb