pmap.h revision 2246
14Srgrimes/* 24Srgrimes * Copyright (c) 1991 Regents of the University of California. 34Srgrimes * All rights reserved. 44Srgrimes * 54Srgrimes * This code is derived from software contributed to Berkeley by 64Srgrimes * the Systems Programming Group of the University of Utah Computer 74Srgrimes * Science Department and William Jolitz of UUNET Technologies Inc. 84Srgrimes * 94Srgrimes * Redistribution and use in source and binary forms, with or without 104Srgrimes * modification, are permitted provided that the following conditions 114Srgrimes * are met: 124Srgrimes * 1. Redistributions of source code must retain the above copyright 134Srgrimes * notice, this list of conditions and the following disclaimer. 144Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 154Srgrimes * notice, this list of conditions and the following disclaimer in the 164Srgrimes * documentation and/or other materials provided with the distribution. 174Srgrimes * 3. All advertising materials mentioning features or use of this software 184Srgrimes * must display the following acknowledgement: 194Srgrimes * This product includes software developed by the University of 204Srgrimes * California, Berkeley and its contributors. 214Srgrimes * 4. Neither the name of the University nor the names of its contributors 224Srgrimes * may be used to endorse or promote products derived from this software 234Srgrimes * without specific prior written permission. 244Srgrimes * 254Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 264Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 274Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 284Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 294Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 304Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 314Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 324Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 334Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 344Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 354Srgrimes * SUCH DAMAGE. 364Srgrimes * 374Srgrimes * Derived from hp300 version by Mike Hibler, this version by William 384Srgrimes * Jolitz uses a recursive map [a pde points to the page directory] to 394Srgrimes * map the page tables using the pagetables themselves. This is done to 404Srgrimes * reduce the impact on kernel virtual memory for lots of sparse address 414Srgrimes * space, and to reduce the cost of memory to each process. 424Srgrimes * 43607Srgrimes * from: hp300: @(#)pmap.h 7.2 (Berkeley) 12/16/90 44607Srgrimes * from: @(#)pmap.h 7.4 (Berkeley) 5/12/91 452246Sdg * $Id: pmap.h,v 1.15 1994/08/18 22:34:47 wollman Exp $ 464Srgrimes */ 474Srgrimes 484Srgrimes#ifndef _PMAP_MACHINE_ 494Srgrimes#define _PMAP_MACHINE_ 1 504Srgrimes 511549Srgrimes#include <machine/pte.h> 524Srgrimes 531246Sdgtypedef unsigned int *pd_entry_t; 541246Sdgtypedef unsigned int *pt_entry_t; 554Srgrimes 564Srgrimes/* 57757Sdg * NKPDE controls the virtual space of the kernel, what ever is left, minus 58757Sdg * the alternate page table area is given to the user (NUPDE) 594Srgrimes */ 60588Srgrimes/* 61974Sdg * NKPDE controls the virtual space of the kernel, what ever is left is 62974Sdg * given to the user (NUPDE) 63974Sdg */ 64974Sdg#ifndef NKPT 652246Sdg#define NKPT 24 /* actual number of kernel page tables */ 66974Sdg#endif 67974Sdg#ifndef NKPDE 682246Sdg#define NKPDE 63 /* addressable number of page tables/pde's */ 69974Sdg#endif 70974Sdg 71974Sdg#define NUPDE (NPTEPG-NKPDE) /* number of user pde's */ 72974Sdg 73974Sdg/* 74588Srgrimes * The *PTDI values control the layout of virtual memory 75588Srgrimes * 76588Srgrimes * XXX This works for now, but I am not real happy with it, I'll fix it 77588Srgrimes * right after I fix locore.s and the magic 28K hole 78588Srgrimes */ 79607Srgrimes#define APTDPTDI (NPTEPG-1) /* alt ptd entry that points to APTD */ 80607Srgrimes#define KPTDI (APTDPTDI-NKPDE)/* start of kernel virtual pde's */ 81589Srgrimes#define PTDPTDI (KPTDI-1) /* ptd entry that points to ptd! */ 82757Sdg#define KSTKPTDI (PTDPTDI-1) /* ptd entry for u./kernel&user stack */ 831246Sdg#define KSTKPTEOFF (NBPG/sizeof(pd_entry_t)-UPAGES) /* pte entry for kernel stack */ 844Srgrimes 851246Sdg#define PDESIZE sizeof(pd_entry_t) /* for assembly files */ 861246Sdg#define PTESIZE sizeof(pt_entry_t) /* for assembly files */ 87757Sdg 884Srgrimes/* 894Srgrimes * Address of current and alternate address space page table maps 904Srgrimes * and directories. 914Srgrimes */ 924Srgrimes#ifdef KERNEL 931246Sdgextern pt_entry_t PTmap[], APTmap[], Upte; 941246Sdgextern pd_entry_t PTD[], APTD[], PTDpde, APTDpde, Upde; 954Srgrimes 964Srgrimesextern int IdlePTD; /* physical address of "Idle" state directory */ 974Srgrimes#endif 984Srgrimes 994Srgrimes/* 1004Srgrimes * virtual address to page table entry and 1014Srgrimes * to physical address. Likewise for alternate address space. 1024Srgrimes * Note: these work recursively, thus vtopte of a pte will give 1034Srgrimes * the corresponding pde that in turn maps it. 1044Srgrimes */ 1054Srgrimes#define vtopte(va) (PTmap + i386_btop(va)) 1064Srgrimes#define kvtopte(va) vtopte(va) 1074Srgrimes#define ptetov(pt) (i386_ptob(pt - PTmap)) 1081246Sdg#define vtophys(va) (((int) (*vtopte(va))&PG_FRAME) | ((int)(va) & PGOFSET)) 109588Srgrimes#define ispt(va) ((va) >= UPT_MIN_ADDRESS && (va) <= KPT_MAX_ADDRESS) 1104Srgrimes 1114Srgrimes#define avtopte(va) (APTmap + i386_btop(va)) 1124Srgrimes#define ptetoav(pt) (i386_ptob(pt - APTmap)) 1131246Sdg#define avtophys(va) (((int) (*avtopte(va))&PG_FRAME) | ((int)(va) & PGOFSET)) 1144Srgrimes 1151310Sdg#ifdef KERNEL 1164Srgrimes/* 1171307Sdg * Routine: pmap_kextract 1181307Sdg * Function: 1191307Sdg * Extract the physical page address associated 1201307Sdg * kernel virtual address. 1211307Sdg */ 1221307Sdgstatic inline vm_offset_t 1231307Sdgpmap_kextract(va) 1241307Sdg vm_offset_t va; 1251307Sdg{ 1261307Sdg vm_offset_t pa = *(int *)vtopte(va); 1271307Sdg pa = (pa & PG_FRAME) | (va & ~PG_FRAME); 1281307Sdg return pa; 1291307Sdg} 1301310Sdg#endif 1311307Sdg 1321307Sdg/* 1334Srgrimes * macros to generate page directory/table indicies 1344Srgrimes */ 1354Srgrimes 1364Srgrimes#define pdei(va) (((va)&PD_MASK)>>PD_SHIFT) 1374Srgrimes#define ptei(va) (((va)&PT_MASK)>>PG_SHIFT) 1384Srgrimes 1394Srgrimes/* 1404Srgrimes * Pmap stuff 1414Srgrimes */ 1424Srgrimes 1434Srgrimesstruct pmap { 1444Srgrimes pd_entry_t *pm_pdir; /* KVA of page directory */ 1454Srgrimes boolean_t pm_pdchanged; /* pdir changed */ 1464Srgrimes short pm_dref; /* page directory ref count */ 1474Srgrimes short pm_count; /* pmap reference count */ 1484Srgrimes simple_lock_data_t pm_lock; /* lock on pmap */ 1494Srgrimes struct pmap_statistics pm_stats; /* pmap statistics */ 1504Srgrimes long pm_ptpages; /* more stats: PT pages */ 1514Srgrimes}; 1524Srgrimes 1534Srgrimestypedef struct pmap *pmap_t; 1544Srgrimes 1554Srgrimes#ifdef KERNEL 1564Srgrimesextern pmap_t kernel_pmap; 1574Srgrimes#endif 1584Srgrimes 1594Srgrimes/* 1604Srgrimes * Macros for speed 1614Srgrimes */ 162588Srgrimes#define PMAP_ACTIVATE(pmapp, pcbp) \ 1634Srgrimes if ((pmapp) != NULL /*&& (pmapp)->pm_pdchanged */) { \ 1644Srgrimes (pcbp)->pcb_cr3 = \ 165879Swollman pmap_extract(kernel_pmap, (vm_offset_t)(pmapp)->pm_pdir); \ 1664Srgrimes if ((pmapp) == &curproc->p_vmspace->vm_pmap) \ 1674Srgrimes load_cr3((pcbp)->pcb_cr3); \ 1684Srgrimes (pmapp)->pm_pdchanged = FALSE; \ 1694Srgrimes } 1704Srgrimes 171588Srgrimes#define PMAP_DEACTIVATE(pmapp, pcbp) 1724Srgrimes 1734Srgrimes/* 1744Srgrimes * For each vm_page_t, there is a list of all currently valid virtual 1754Srgrimes * mappings of that page. An entry is a pv_entry_t, the list is pv_table. 1764Srgrimes */ 1774Srgrimestypedef struct pv_entry { 1784Srgrimes struct pv_entry *pv_next; /* next pv_entry */ 1794Srgrimes pmap_t pv_pmap; /* pmap where mapping lies */ 1804Srgrimes vm_offset_t pv_va; /* virtual address for mapping */ 1814Srgrimes} *pv_entry_t; 1824Srgrimes 1834Srgrimes#define PV_ENTRY_NULL ((pv_entry_t) 0) 1844Srgrimes 1854Srgrimes#define PV_CI 0x01 /* all entries must be cache inhibited */ 186588Srgrimes#define PV_PTPAGE 0x02 /* entry maps a page table page */ 1874Srgrimes 1884Srgrimes#ifdef KERNEL 1894Srgrimes 1904Srgrimespv_entry_t pv_table; /* array of entries, one per page */ 1914Srgrimes 192588Srgrimes#define pa_index(pa) atop(pa - vm_first_phys) 193588Srgrimes#define pa_to_pvh(pa) (&pv_table[pa_index(pa)]) 1944Srgrimes 1954Srgrimes#define pmap_resident_count(pmap) ((pmap)->pm_stats.resident_count) 1964Srgrimes 1971246Sdgextern inline pt_entry_t *pmap_pte(pmap_t, vm_offset_t); 198879Swollmanstruct pcb; extern void pmap_activate(pmap_t, struct pcb *); 199879Swollmanextern pmap_t pmap_kernel(void); 200879Swollman 201719Swollman#endif /* KERNEL */ 2024Srgrimes 203719Swollman#endif /* _PMAP_MACHINE_ */ 204