pgtable.h

来自「基于组件方式开发操作系统的OSKIT源代码」· C头文件 代码 · 共 638 行 · 第 1/2 页

H
638
字号
#define PMD_TYPE_MASK		0x0003#define PMD_TYPE_FAULT		0x0000#define PMD_TYPE_TABLE		0x0001#define PMD_TYPE_SECT		0x0002#define PMD_UPDATABLE		0x0010#define PMD_SECT_CACHEABLE	0x0008#define PMD_SECT_BUFFERABLE	0x0004#define PMD_SECT_AP_WRITE	0x0400#define PMD_SECT_AP_READ	0x0800#define PMD_DOMAIN(x)		((x) << 5)#define _PAGE_USER_TABLE	(PMD_TYPE_TABLE | PMD_DOMAIN(DOMAIN_USER))#define _PAGE_KERNEL_TABLE	(PMD_TYPE_TABLE | PMD_DOMAIN(DOMAIN_KERNEL))#define pmd_none(pmd)		(!pmd_val(pmd))#define pmd_clear(pmdp)		set_pmd(pmdp, __pmd(0))#define pmd_bad(pmd)		(pmd_val(pmd) & 2)#define mk_user_pmd(ptep)	__mk_pmd(ptep, _PAGE_USER_TABLE)#define mk_kernel_pmd(ptep)	__mk_pmd(ptep, _PAGE_KERNEL_TABLE)#define set_pmd(pmdp,pmd)	processor.u.armv3v4._set_pmd(pmdp,pmd)/* Find an entry in the second-level page table.. */#define pmd_offset(dir, address) ((pmd_t *)(dir))extern __inline__ int pmd_present(pmd_t pmd){	return ((pmd_val(pmd) + 1) & 2);}/* We don't use pmd cache, so this is a dummy routine */extern __inline__ pmd_t *get_pmd_fast(void){	return (pmd_t *)0;}extern __inline__ void free_pmd_fast(pmd_t *pmd){}extern __inline__ void free_pmd_slow(pmd_t *pmd){}extern void __bad_pmd(pmd_t *pmd);extern void __bad_pmd_kernel(pmd_t *pmd);/* * allocating and freeing a pmd is trivial: the 1-entry pmd is * inside the pgd, so has no extra memory associated with it. */extern __inline__ void pmd_free(pmd_t *pmd){}extern __inline__ pmd_t *pmd_alloc(pgd_t *pgd, unsigned long address){	return (pmd_t *) pgd;}#define pmd_free_kernel		pmd_free#define pmd_alloc_kernel	pmd_allocextern __inline__ pmd_t __mk_pmd(pte_t *ptep, unsigned long prot){	unsigned long pte_ptr = (unsigned long)ptep;	pmd_t pmd;	pte_ptr -= PTRS_PER_PTE * BYTES_PER_PTR;	/*	 * The pmd must be loaded with the physical	 * address of the PTE table	 */	pmd_val(pmd) = __virt_to_phys(pte_ptr) | prot;	return pmd;}extern __inline__ unsigned long pmd_page(pmd_t pmd){	unsigned long ptr;	ptr = pmd_val(pmd) & ~(PTRS_PER_PTE * BYTES_PER_PTR - 1);	ptr += PTRS_PER_PTE * BYTES_PER_PTR;	return __phys_to_virt(ptr);}/***************** PTE functions *****************//* PTE types (actially level 2 descriptor) */#define PTE_TYPE_MASK		0x0003#define PTE_TYPE_FAULT		0x0000#define PTE_TYPE_LARGE		0x0001#define PTE_TYPE_SMALL		0x0002#define PTE_AP_READ		0x0aa0#define PTE_AP_WRITE		0x0550#define PTE_CACHEABLE		0x0008#define PTE_BUFFERABLE		0x0004#define pte_none(pte)		(!pte_val(pte))#define pte_clear(ptep)		set_pte(ptep, __pte(0))/* * Conversion functions: convert a page and protection to a page entry, * and a page entry and page directory to the page they refer to. */extern __inline__ pte_t mk_pte(unsigned long page, pgprot_t pgprot){	pte_t pte;	pte_val(pte) = __virt_to_phys(page) | pgprot_val(pgprot);	return pte;}/* This takes a physical page address that is used by the remapping functions */extern __inline__ pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot){	pte_t pte;	pte_val(pte) = physpage + pgprot_val(pgprot);	return pte;}#define set_pte(ptep, pte)	processor.u.armv3v4._set_pte(ptep,pte)extern __inline__ unsigned long pte_page(pte_t pte){	return __phys_to_virt(pte_val(pte) & PAGE_MASK);}extern pte_t *get_pte_slow(pmd_t *pmd, unsigned long address_preadjusted);extern pte_t *get_pte_kernel_slow(pmd_t *pmd, unsigned long address_preadjusted);extern __inline__ pte_t *get_pte_fast(void){	unsigned long *ret;	if((ret = (unsigned long *)pte_quicklist) != NULL) {		pte_quicklist = (unsigned long *)(*ret);		ret[0] = ret[1];		clean_cache_area(ret, 4);		pgtable_cache_size--;	}	return (pte_t *)ret;}extern __inline__ void free_pte_fast(pte_t *pte){	*(unsigned long *)pte = (unsigned long) pte_quicklist;	pte_quicklist = (unsigned long *) pte;	pgtable_cache_size++;}extern __inline__ void free_pte_slow(pte_t *pte){	free_page_2k((unsigned long)(pte - PTRS_PER_PTE));}#define pte_free_kernel(pte)	free_pte_fast(pte)#define pte_free(pte)		free_pte_fast(pte)/*############################################################################### * New PageTableEntry stuff... *//* We now keep two sets of ptes - the physical and the linux version. * This gives us many advantages, and allows us greater flexibility. * * The Linux pte's contain: *  bit   meaning *   0    page present *   1    young *   2    bufferable	- matches physical pte *   3    cacheable	- matches physical pte *   4    user *   5    write *   6    execute *   7    dirty *  8-11  unused *  12-31 virtual page address * * These are stored at the pte pointer; the physical PTE is at -1024bytes */#define L_PTE_PRESENT		(1 << 0)#define L_PTE_YOUNG		(1 << 1)#define L_PTE_BUFFERABLE	(1 << 2)#define L_PTE_CACHEABLE		(1 << 3)#define L_PTE_USER		(1 << 4)#define L_PTE_WRITE		(1 << 5)#define L_PTE_EXEC		(1 << 6)#define L_PTE_DIRTY		(1 << 7)/* * The following macros handle the cache and bufferable bits... */#define _L_PTE_DEFAULT	L_PTE_PRESENT | L_PTE_YOUNG#define _L_PTE_READ	L_PTE_USER | L_PTE_CACHEABLE#define _L_PTE_EXEC	_L_PTE_READ | L_PTE_EXEC#define PAGE_NONE       __pgprot(_L_PTE_DEFAULT)#define PAGE_COPY       __pgprot(_L_PTE_DEFAULT | _L_PTE_READ  | L_PTE_BUFFERABLE)#define PAGE_SHARED     __pgprot(_L_PTE_DEFAULT | _L_PTE_READ  | L_PTE_BUFFERABLE | L_PTE_WRITE)#define PAGE_READONLY   __pgprot(_L_PTE_DEFAULT | _L_PTE_READ)#define PAGE_KERNEL     __pgprot(_L_PTE_DEFAULT | L_PTE_CACHEABLE | L_PTE_BUFFERABLE | L_PTE_DIRTY | L_PTE_WRITE)#define _PAGE_CHG_MASK		(PAGE_MASK | L_PTE_DIRTY | L_PTE_YOUNG)/* * The table below defines the page protection levels that we insert into our * Linux page table version.  These get translated into the best that the * architecture can perform.  Note that on most ARM hardware: *  1) We cannot do execute protection *  2) If we could do execute protection, then read is implied *  3) write implies read permissions */#define __P000  PAGE_NONE#define __P001  PAGE_READONLY#define __P010  PAGE_COPY#define __P011  PAGE_COPY#define __P100  PAGE_READONLY#define __P101  PAGE_READONLY#define __P110  PAGE_COPY#define __P111  PAGE_COPY#define __S000  PAGE_NONE#define __S001  PAGE_READONLY#define __S010  PAGE_SHARED#define __S011  PAGE_SHARED#define __S100  PAGE_READONLY#define __S101  PAGE_READONLY#define __S110  PAGE_SHARED#define __S111  PAGE_SHARED#define pte_present(pte)	(pte_val(pte) & L_PTE_PRESENT)/* * The following only work if pte_present() is true. * Undefined behaviour if not.. */#define pte_read(pte)			(pte_val(pte) & L_PTE_USER)#define pte_write(pte)			(pte_val(pte) & L_PTE_WRITE)#define pte_exec(pte)			(pte_val(pte) & L_PTE_EXEC)#define pte_dirty(pte)			(pte_val(pte) & L_PTE_DIRTY)#define pte_young(pte)			(pte_val(pte) & L_PTE_YOUNG)#define PTE_BIT_FUNC(fn,op)			\extern inline pte_t fn##(pte_t pte) { pte_val(pte) op##; return pte; }//PTE_BIT_FUNC(pte_rdprotect, &= ~L_PTE_USER);PTE_BIT_FUNC(pte_wrprotect, &= ~L_PTE_WRITE);PTE_BIT_FUNC(pte_exprotect, &= ~L_PTE_EXEC);PTE_BIT_FUNC(pte_mkclean,   &= ~L_PTE_DIRTY);PTE_BIT_FUNC(pte_mkold,     &= ~L_PTE_YOUNG);//PTE_BIT_FUNC(pte_mkread,    |= L_PTE_USER);PTE_BIT_FUNC(pte_mkwrite,   |= L_PTE_WRITE);PTE_BIT_FUNC(pte_mkexec,    |= L_PTE_EXEC);PTE_BIT_FUNC(pte_mkdirty,   |= L_PTE_DIRTY);PTE_BIT_FUNC(pte_mkyoung,   |= L_PTE_YOUNG);PTE_BIT_FUNC(pte_nocache,   &= ~L_PTE_CACHEABLE);extern __inline__ pte_t pte_modify(pte_t pte, pgprot_t newprot){	pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot);	return pte;}/* Find an entry in the third-level page table.. */extern __inline__ pte_t * pte_offset(pmd_t * dir, unsigned long address){	return (pte_t *) pmd_page(*dir) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1));}extern __inline__ pte_t * pte_alloc_kernel(pmd_t *pmd, unsigned long address){	address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);	if (pmd_none(*pmd)) {		pte_t *page = (pte_t *) get_pte_fast();		if (!page)			return get_pte_kernel_slow(pmd, address);		set_pmd(pmd, mk_kernel_pmd(page));		return page + address;	}	if (pmd_bad(*pmd)) {		__bad_pmd_kernel(pmd);		return NULL;	}	return (pte_t *) pmd_page(*pmd) + address;}extern __inline__ pte_t * pte_alloc(pmd_t * pmd, unsigned long address){	address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);	if (pmd_none(*pmd)) {		pte_t *page = (pte_t *) get_pte_fast();		if (!page)			return get_pte_slow(pmd, address);		set_pmd(pmd, mk_user_pmd(page));		return page + address;	}	if (pmd_bad(*pmd)) {		__bad_pmd(pmd);		return NULL;	}	return (pte_t *) pmd_page(*pmd) + address;}#define SWP_TYPE(entry) (((entry) >> 2) & 0x7f)#define SWP_OFFSET(entry) ((entry) >> 9)#define SWP_ENTRY(type,offset) (((type) << 2) | ((offset) << 9))#endif /* __ASM_PROC_PAGE_H */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?