Annotation of sys/arch/alpha/include/pmap.h, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: pmap.h,v 1.21 2006/02/07 07:59:23 martin Exp $ */
! 2: /* $NetBSD: pmap.h,v 1.37 2000/11/19 03:16:35 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) 1987 Carnegie-Mellon University
! 43: * Copyright (c) 1991, 1993
! 44: * The Regents of the University of California. All rights reserved.
! 45: *
! 46: * This code is derived from software contributed to Berkeley by
! 47: * the Systems Programming Group of the University of Utah Computer
! 48: * Science Department.
! 49: *
! 50: * Redistribution and use in source and binary forms, with or without
! 51: * modification, are permitted provided that the following conditions
! 52: * are met:
! 53: * 1. Redistributions of source code must retain the above copyright
! 54: * notice, this list of conditions and the following disclaimer.
! 55: * 2. Redistributions in binary form must reproduce the above copyright
! 56: * notice, this list of conditions and the following disclaimer in the
! 57: * documentation and/or other materials provided with the distribution.
! 58: * 3. Neither the name of the University nor the names of its contributors
! 59: * may be used to endorse or promote products derived from this software
! 60: * without specific prior written permission.
! 61: *
! 62: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
! 63: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 64: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 65: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
! 66: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 67: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 68: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 69: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 70: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 71: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 72: * SUCH DAMAGE.
! 73: *
! 74: * @(#)pmap.h 8.1 (Berkeley) 6/10/93
! 75: */
! 76:
! 77: #ifndef _PMAP_MACHINE_
! 78: #define _PMAP_MACHINE_
! 79:
! 80: #include <sys/lock.h>
! 81: #include <sys/queue.h>
! 82:
! 83: #include <machine/pte.h>
! 84:
! 85: /*
! 86: * Machine-dependent virtual memory state.
! 87: *
! 88: * If we ever support processor numbers higher than 63, we'll have to
! 89: * rethink the CPU mask.
! 90: *
! 91: * Note pm_asn and pm_asngen are arrays allocated in pmap_create().
! 92: * Their size is based on the PCS count from the HWRPB, and indexed
! 93: * by processor ID (from `whami').
! 94: *
! 95: * The kernel pmap is a special case; it gets statically-allocated
! 96: * arrays which hold enough for ALPHA_MAXPROCS.
! 97: */
! 98: struct pmap {
! 99: TAILQ_ENTRY(pmap) pm_list; /* list of all pmaps */
! 100: pt_entry_t *pm_lev1map; /* level 1 map */
! 101: int pm_count; /* pmap reference count */
! 102: struct simplelock pm_slock; /* lock on pmap */
! 103: struct pmap_statistics pm_stats; /* pmap statistics */
! 104: long pm_nlev2; /* level 2 pt page count */
! 105: long pm_nlev3; /* level 3 pt page count */
! 106: unsigned int *pm_asn; /* address space number */
! 107: unsigned long *pm_asngen; /* ASN generation number */
! 108: unsigned long pm_cpus; /* mask of CPUs using pmap */
! 109: unsigned long pm_needisync; /* mask of CPUs needing isync */
! 110: };
! 111:
! 112: typedef struct pmap *pmap_t;
! 113:
! 114: #define PMAP_ASN_RESERVED 0 /* reserved for Lev1map users */
! 115:
! 116: extern struct pmap kernel_pmap_store;
! 117:
! 118: #define pmap_kernel() (&kernel_pmap_store)
! 119:
! 120: /*
! 121: * For each vm_page_t, there is a list of all currently valid virtual
! 122: * mappings of that page. An entry is a pv_entry_t, the list is pv_table.
! 123: */
! 124: typedef struct pv_entry {
! 125: LIST_ENTRY(pv_entry) pv_list; /* pv_entry list */
! 126: struct pmap *pv_pmap; /* pmap where mapping lies */
! 127: vaddr_t pv_va; /* virtual address for mapping */
! 128: pt_entry_t *pv_pte; /* PTE that maps the VA */
! 129: } *pv_entry_t;
! 130:
! 131: /*
! 132: * The head of the list of pv_entry_t's, also contains page attributes.
! 133: */
! 134: struct pv_head {
! 135: LIST_HEAD(, pv_entry) pvh_list; /* pv_entry list */
! 136: struct simplelock pvh_slock; /* lock on this head */
! 137: int pvh_attrs; /* page attributes */
! 138: int pvh_usage; /* page usage */
! 139: int pvh_refcnt; /* special use ref count */
! 140: };
! 141:
! 142: /* pvh_attrs */
! 143: #define PGA_MODIFIED 0x01 /* modified */
! 144: #define PGA_REFERENCED 0x02 /* referenced */
! 145:
! 146: /* pvh_usage */
! 147: #define PGU_NORMAL 0 /* free or normal use */
! 148: #define PGU_PVENT 1 /* PV entries */
! 149: #define PGU_L1PT 2 /* level 1 page table */
! 150: #define PGU_L2PT 3 /* level 2 page table */
! 151: #define PGU_L3PT 4 /* level 3 page table */
! 152:
! 153: #define PGU_ISPTPAGE(pgu) ((pgu) >= PGU_L1PT)
! 154:
! 155: #define PGU_STRINGS \
! 156: { \
! 157: "normal", \
! 158: "pvent", \
! 159: "l1pt", \
! 160: "l2pt", \
! 161: "l3pt", \
! 162: }
! 163:
! 164: #ifdef _KERNEL
! 165:
! 166: #ifndef _LKM
! 167: #if defined(NEW_SCC_DRIVER)
! 168: #if defined(DEC_KN8AE)
! 169: #define _PMAP_MAY_USE_PROM_CONSOLE
! 170: #endif
! 171: #else /* ! NEW_SCC_DRIVER */
! 172: #if defined(DEC_3000_300) \
! 173: || defined(DEC_3000_500) \
! 174: || defined(DEC_KN8AE) /* XXX */
! 175: #define _PMAP_MAY_USE_PROM_CONSOLE /* XXX */
! 176: #endif /* XXX */
! 177: #endif /* NEW_SCC_DRIVER */
! 178:
! 179: #if defined(MULTIPROCESSOR)
! 180: void pmap_tlb_shootdown(pmap_t, vaddr_t, pt_entry_t);
! 181: void pmap_do_tlb_shootdown(struct cpu_info *, struct trapframe *);
! 182: void pmap_tlb_shootdown_q_drain(u_long, boolean_t);
! 183: #define PMAP_TLB_SHOOTDOWN(pm, va, pte) \
! 184: pmap_tlb_shootdown((pm), (va), (pte))
! 185: #else
! 186: #define PMAP_TLB_SHOOTDOWN(pm, va, pte) /* nothing */
! 187: #endif /* MULTIPROCESSOR */
! 188: #endif /* _LKM */
! 189:
! 190: #define pmap_resident_count(pmap) ((pmap)->pm_stats.resident_count)
! 191: #define pmap_wired_count(pmap) ((pmap)->pm_stats.wired_count)
! 192: #define pmap_update(pmap) /* nothing (yet) */
! 193: #define pmap_phys_address(ppn) ptoa(ppn)
! 194:
! 195: #define pmap_proc_iflush(p, va, len) /* nothing */
! 196: #define pmap_unuse_final(p) /* nothing */
! 197:
! 198: extern pt_entry_t *VPT; /* Virtual Page Table */
! 199:
! 200: #define PMAP_STEAL_MEMORY /* enable pmap_steal_memory() */
! 201: #define PMAP_GROWKERNEL /* enable pmap_growkernel() */
! 202:
! 203: /*
! 204: * Alternate mapping hooks for pool pages. Avoids thrashing the TLB.
! 205: */
! 206: #define pmap_map_direct(pg) ALPHA_PHYS_TO_K0SEG(VM_PAGE_TO_PHYS(pg))
! 207: #define pmap_unmap_direct(va) PHYS_TO_VM_PAGE(ALPHA_K0SEG_TO_PHYS((va)))
! 208: #define __HAVE_PMAP_DIRECT
! 209:
! 210: paddr_t vtophys(vaddr_t);
! 211:
! 212: /* Machine-specific functions. */
! 213: void pmap_bootstrap(paddr_t ptaddr, u_int maxasn, u_long ncpuids);
! 214: int pmap_emulate_reference(struct proc *p, vaddr_t v, int user, int type);
! 215: #ifdef _PMAP_MAY_USE_PROM_CONSOLE
! 216: int pmap_uses_prom_console(void);
! 217: #endif
! 218:
! 219: #define pmap_pte_pa(pte) (PG_PFNUM(*(pte)) << PGSHIFT)
! 220: #define pmap_pte_prot(pte) (*(pte) & PG_PROT)
! 221: #define pmap_pte_w(pte) (*(pte) & PG_WIRED)
! 222: #define pmap_pte_v(pte) (*(pte) & PG_V)
! 223: #define pmap_pte_pv(pte) (*(pte) & PG_PVLIST)
! 224: #define pmap_pte_asm(pte) (*(pte) & PG_ASM)
! 225: #define pmap_pte_exec(pte) (*(pte) & PG_EXEC)
! 226:
! 227: #define pmap_pte_set_w(pte, v) \
! 228: do { \
! 229: if (v) \
! 230: *(pte) |= PG_WIRED; \
! 231: else \
! 232: *(pte) &= ~PG_WIRED; \
! 233: } while (0)
! 234:
! 235: #define pmap_pte_w_chg(pte, nw) ((nw) ^ pmap_pte_w(pte))
! 236:
! 237: #define pmap_pte_set_prot(pte, np) \
! 238: do { \
! 239: *(pte) &= ~PG_PROT; \
! 240: *(pte) |= (np); \
! 241: } while (0)
! 242:
! 243: #define pmap_pte_prot_chg(pte, np) ((np) ^ pmap_pte_prot(pte))
! 244:
! 245: static __inline pt_entry_t *pmap_l2pte(pmap_t, vaddr_t, pt_entry_t *);
! 246: static __inline pt_entry_t *pmap_l3pte(pmap_t, vaddr_t, pt_entry_t *);
! 247:
! 248: #define pmap_l1pte(pmap, v) \
! 249: (&(pmap)->pm_lev1map[l1pte_index((vaddr_t)(v))])
! 250:
! 251: static __inline pt_entry_t *
! 252: pmap_l2pte(pmap, v, l1pte)
! 253: pmap_t pmap;
! 254: vaddr_t v;
! 255: pt_entry_t *l1pte;
! 256: {
! 257: pt_entry_t *lev2map;
! 258:
! 259: if (l1pte == NULL) {
! 260: l1pte = pmap_l1pte(pmap, v);
! 261: if (pmap_pte_v(l1pte) == 0)
! 262: return (NULL);
! 263: }
! 264:
! 265: lev2map = (pt_entry_t *)ALPHA_PHYS_TO_K0SEG(pmap_pte_pa(l1pte));
! 266: return (&lev2map[l2pte_index(v)]);
! 267: }
! 268:
! 269: static __inline pt_entry_t *
! 270: pmap_l3pte(pmap, v, l2pte)
! 271: pmap_t pmap;
! 272: vaddr_t v;
! 273: pt_entry_t *l2pte;
! 274: {
! 275: pt_entry_t *l1pte, *lev2map, *lev3map;
! 276:
! 277: if (l2pte == NULL) {
! 278: l1pte = pmap_l1pte(pmap, v);
! 279: if (pmap_pte_v(l1pte) == 0)
! 280: return (NULL);
! 281:
! 282: lev2map = (pt_entry_t *)ALPHA_PHYS_TO_K0SEG(pmap_pte_pa(l1pte));
! 283: l2pte = &lev2map[l2pte_index(v)];
! 284: if (pmap_pte_v(l2pte) == 0)
! 285: return (NULL);
! 286: }
! 287:
! 288: lev3map = (pt_entry_t *)ALPHA_PHYS_TO_K0SEG(pmap_pte_pa(l2pte));
! 289: return (&lev3map[l3pte_index(v)]);
! 290: }
! 291:
! 292: /*
! 293: * Macros for locking pmap structures.
! 294: *
! 295: * Note that we if we access the kernel pmap in interrupt context, it
! 296: * is only to update statistics. Since stats are updated using atomic
! 297: * operations, locking the kernel pmap is not necessary. Therefore,
! 298: * it is not necessary to block interrupts when locking pmap structures.
! 299: */
! 300: #define PMAP_LOCK(pmap) simple_lock(&(pmap)->pm_slock)
! 301: #define PMAP_UNLOCK(pmap) simple_unlock(&(pmap)->pm_slock)
! 302:
! 303: /*
! 304: * Macro for processing deferred I-stream synchronization.
! 305: *
! 306: * The pmap module may defer syncing the user I-stream until the
! 307: * return to userspace, since the IMB PALcode op can be quite
! 308: * expensive. Since user instructions won't be executed until
! 309: * the return to userspace, this can be deferred until userret().
! 310: */
! 311: #define PMAP_USERRET(pmap) \
! 312: do { \
! 313: u_long cpu_mask = (1UL << cpu_number()); \
! 314: \
! 315: if ((pmap)->pm_needisync & cpu_mask) { \
! 316: atomic_clearbits_ulong(&(pmap)->pm_needisync, \
! 317: cpu_mask); \
! 318: alpha_pal_imb(); \
! 319: } \
! 320: } while (0)
! 321:
! 322: #endif /* _KERNEL */
! 323:
! 324: #endif /* _PMAP_MACHINE_ */
CVSweb