pmap.h
来自「基于组件方式开发操作系统的OSKIT源代码」· C头文件 代码 · 共 541 行 · 第 1/2 页
H
541 行
* describes one mapping). */struct pv_entry;struct pv_head { simple_lock_data_t pvh_lock; /* locks every pv on this list */ struct pv_entry *pvh_list; /* head of list (locked by pvh_lock) */};struct pv_entry { /* locked by its list's pvh_lock */ struct pv_entry *pv_next; /* next entry */ struct pmap *pv_pmap; /* the pmap */ vaddr_t pv_va; /* the virtual address */ struct vm_page *pv_ptp; /* the vm_page of the PTP */};/* * pv_entrys are dynamically allocated in chunks from a single page. * we keep track of how many pv_entrys are in use for each page and * we can free pv_entry pages if needed. there is one lock for the * entire allocation system. */struct pv_page_info { TAILQ_ENTRY(pv_page) pvpi_list; struct pv_entry *pvpi_pvfree; int pvpi_nfree;};/* * number of pv_entry's in a pv_page * (note: won't work on systems where NPBG isn't a constant) */#define PVE_PER_PVPAGE ((NBPG - sizeof(struct pv_page_info)) / \ sizeof(struct pv_entry))/* * a pv_page: where pv_entrys are allocated from */struct pv_page { struct pv_page_info pvinfo; struct pv_entry pvents[PVE_PER_PVPAGE];};/* * pmap_remove_record: a record of VAs that have been unmapped, used to * flush TLB. if we have more than PMAP_RR_MAX then we stop recording. */#define PMAP_RR_MAX 16 /* max of 16 pages (64K) */struct pmap_remove_record { int prr_npages; vaddr_t prr_vas[PMAP_RR_MAX];};#if 0/* * pmap_transfer_location: used to pass the current location in the * pmap between pmap_transfer and pmap_transfer_ptes [e.g. during * a pmap_copy]. */struct pmap_transfer_location { vaddr_t addr; /* the address (page-aligned) */ pt_entry_t *pte; /* the PTE that maps address */ struct vm_page *ptp; /* the PTP that the PTE lives in */};#endif/* * global kernel variables *//* PTDpaddr: is the physical address of the kernel's PDP */extern u_long PTDpaddr;extern struct pmap kernel_pmap_store; /* kernel pmap */extern int nkpde; /* current # of PDEs for kernel */extern int pmap_pg_g; /* do we support PG_G? *//* * macros */#define pmap_kernel() (&kernel_pmap_store)#define pmap_resident_count(pmap) ((pmap)->pm_stats.resident_count)#define pmap_wired_count(pmap) ((pmap)->pm_stats.wired_count)#define pmap_update() tlbflush()#define pmap_clear_modify(pg) pmap_change_attrs(pg, 0, PG_M)#define pmap_clear_reference(pg) pmap_change_attrs(pg, 0, PG_U)#define pmap_copy(DP,SP,D,L,S) #define pmap_is_modified(pg) pmap_test_attrs(pg, PG_M)#define pmap_is_referenced(pg) pmap_test_attrs(pg, PG_U)#define pmap_move(DP,SP,D,L,S) #define pmap_phys_address(ppn) i386_ptob(ppn)#define pmap_valid_entry(E) ((E) & PG_V) /* is PDE or PTE valid? *//* * prototypes */void pmap_activate __P((struct proc *));void pmap_bootstrap __P((vaddr_t));boolean_t pmap_change_attrs __P((struct vm_page *, int, int));void pmap_deactivate __P((struct proc *));static void pmap_page_protect __P((struct vm_page *, vm_prot_t));void pmap_page_remove __P((struct vm_page *));static void pmap_protect __P((struct pmap *, vaddr_t, vaddr_t, vm_prot_t));void pmap_remove __P((struct pmap *, vaddr_t, vaddr_t));boolean_t pmap_test_attrs __P((struct vm_page *, int));void pmap_transfer __P((struct pmap *, struct pmap *, vaddr_t, vsize_t, vaddr_t, boolean_t));static void pmap_update_pg __P((vaddr_t));static void pmap_update_2pg __P((vaddr_t,vaddr_t));void pmap_write_protect __P((struct pmap *, vaddr_t, vaddr_t, vm_prot_t));vaddr_t reserve_dumppages __P((vaddr_t)); /* XXX: not a pmap fn */#define PMAP_GROWKERNEL /* turn on pmap_growkernel interface *//* * Do idle page zero'ing uncached to avoid polluting the cache. */boolean_t pmap_zero_page_uncached __P((paddr_t));#define PMAP_PAGEIDLEZERO(pa) pmap_zero_page_uncached((pa))/* * inline functions *//* * pmap_update_pg: flush one page from the TLB (or flush the whole thing * if hardware doesn't support one-page flushing) */__inline static voidpmap_update_pg(va) vaddr_t va;{#if defined(I386_CPU) if (cpu_class == CPUCLASS_386) pmap_update(); else#endif invlpg((u_int) va);}/* * pmap_update_2pg: flush two pages from the TLB */__inline static voidpmap_update_2pg(va, vb) vaddr_t va, vb;{#if defined(I386_CPU) if (cpu_class == CPUCLASS_386) pmap_update(); else#endif { invlpg((u_int) va); invlpg((u_int) vb); }}/* * pmap_page_protect: change the protection of all recorded mappings * of a managed page * * => this function is a frontend for pmap_page_remove/pmap_change_attrs * => we only have to worry about making the page more protected. * unprotecting a page is done on-demand at fault time. */__inline static voidpmap_page_protect(pg, prot) struct vm_page *pg; vm_prot_t prot;{ if ((prot & VM_PROT_WRITE) == 0) { if (prot & (VM_PROT_READ|VM_PROT_EXECUTE)) { (void) pmap_change_attrs(pg, PG_RO, PG_RW); } else { pmap_page_remove(pg); } }}/* * pmap_protect: change the protection of pages in a pmap * * => this function is a frontend for pmap_remove/pmap_write_protect * => we only have to worry about making the page more protected. * unprotecting a page is done on-demand at fault time. */__inline static voidpmap_protect(pmap, sva, eva, prot) struct pmap *pmap; vaddr_t sva, eva; vm_prot_t prot;{ if ((prot & VM_PROT_WRITE) == 0) { if (prot & (VM_PROT_READ|VM_PROT_EXECUTE)) { pmap_write_protect(pmap, sva, eva, prot); } else { pmap_remove(pmap, sva, eva); } }}/* * various address inlines * * vtopte: return a pointer to the PTE mapping a VA, works only for * user and PT addresses * * kvtopte: return a pointer to the PTE mapping a kernel VA */#include <lib/libkern/libkern.h>static __inline pt_entry_t *vtopte(vaddr_t va){ KASSERT(va < (PDSLOT_KERN << PDSHIFT)); return (PTE_BASE + i386_btop(va));}static __inline pt_entry_t *kvtopte(vaddr_t va){ KASSERT(va >= (PDSLOT_KERN << PDSHIFT));#ifdef LARGEPAGES { pd_entry_t *pde; pde = PDP_BASE + pdei(va); if (*pde & PG_PS) return ((pt_entry_t *)pde); }#endif return (PTE_BASE + i386_btop(va));}paddr_t vtophys __P((vaddr_t));vaddr_t pmap_map __P((vaddr_t, paddr_t, paddr_t, vm_prot_t));#if defined(USER_LDT)void pmap_ldt_cleanup __P((struct proc *));#define PMAP_FORK#endif /* USER_LDT */#endif /* _KERNEL */#endif /* _I386_PMAP_H_ */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?