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 + -
显示快捷键?