pgtable.h
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:15k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * This file is subject to the terms and conditions of the GNU General Public
  3.  * License.  See the file "COPYING" in the main directory of this archive
  4.  * for more details.
  5.  *
  6.  * Copyright (C) 1994, 95, 96, 97, 98, 99, 2000 by Ralf Baechle at alii
  7.  * Copyright (C) 1999 Silicon Graphics, Inc.
  8.  */
  9. #ifndef _ASM_PGTABLE_H
  10. #define _ASM_PGTABLE_H
  11. #include <linux/config.h>
  12. #include <asm/addrspace.h>
  13. #include <asm/page.h>
  14. #include <linux/linkage.h>
  15. #include <asm/cachectl.h>
  16. #include <asm/fixmap.h>
  17. /* Cache flushing:
  18.  *
  19.  *  - flush_cache_all() flushes entire cache
  20.  *  - flush_cache_mm(mm) flushes the specified mm context's cache lines
  21.  *  - flush_cache_page(mm, vmaddr) flushes a single page
  22.  *  - flush_cache_range(mm, start, end) flushes a range of pages
  23.  *  - flush_page_to_ram(page) write back kernel page to ram
  24.  *  - flush_icache_range(start, end) flush a range of instructions
  25.  *
  26.  *  - flush_cache_sigtramp() flush signal trampoline
  27.  *  - flush_icache_all() flush the entire instruction cache
  28.  */
  29. extern void (*_flush_cache_all)(void);
  30. extern void (*___flush_cache_all)(void);
  31. extern void (*_flush_cache_mm)(struct mm_struct *mm);
  32. extern void (*_flush_cache_range)(struct mm_struct *mm, unsigned long start,
  33. unsigned long end);
  34. extern void (*_flush_cache_page)(struct vm_area_struct *vma,
  35. unsigned long page);
  36. extern void (*_flush_page_to_ram)(struct page * page);
  37. extern void (*_flush_icache_range)(unsigned long start, unsigned long end);
  38. extern void (*_flush_icache_page)(struct vm_area_struct *vma,
  39. struct page *page);
  40. extern void (*_flush_cache_sigtramp)(unsigned long addr);
  41. extern void (*_flush_icache_all)(void);
  42. #define flush_dcache_page(page) do { } while (0)
  43. #define flush_cache_all() _flush_cache_all()
  44. #define __flush_cache_all() ___flush_cache_all()
  45. #define flush_cache_mm(mm) _flush_cache_mm(mm)
  46. #define flush_cache_range(mm,start,end) _flush_cache_range(mm,start,end)
  47. #define flush_cache_page(vma,page) _flush_cache_page(vma, page)
  48. #define flush_page_to_ram(page) _flush_page_to_ram(page)
  49. #define flush_icache_range(start, end) _flush_icache_range(start,end)
  50. #define flush_icache_user_range(vma, page, addr, len) 
  51. _flush_icache_page((vma), (page))
  52. #define flush_icache_page(vma, page)  _flush_icache_page(vma, page)
  53. #define flush_cache_sigtramp(addr) _flush_cache_sigtramp(addr)
  54. #ifdef CONFIG_VTAG_ICACHE
  55. #define flush_icache_all() _flush_icache_all()
  56. #else
  57. #define flush_icache_all() do { } while(0)
  58. #endif
  59. /*
  60.  * - add_wired_entry() add a fixed TLB entry, and move wired register
  61.  */
  62. extern void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
  63.        unsigned long entryhi, unsigned long pagemask);
  64. /*
  65.  * - add_temporary_entry() add a temporary TLB entry. We use TLB entries
  66.  * starting at the top and working down. This is for populating the
  67.  * TLB before trap_init() puts the TLB miss handler in place. It
  68.  * should be used only for entries matching the actual page tables,
  69.  * to prevent inconsistencies.
  70.  */
  71. extern int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1,
  72.        unsigned long entryhi, unsigned long pagemask);
  73. /* Basically we have the same two-level (which is the logical three level
  74.  * Linux page table layout folded) page tables as the i386.  Some day
  75.  * when we have proper page coloring support we can have a 1% quicker
  76.  * tlb refill handling mechanism, but for now it is a bit slower but
  77.  * works even with the cache aliasing problem the R4k and above have.
  78.  */
  79. /* PMD_SHIFT determines the size of the area a second-level page table can map */
  80. #ifdef CONFIG_64BIT_PHYS_ADDR
  81. #define PMD_SHIFT 21
  82. #else
  83. #define PMD_SHIFT 22
  84. #endif
  85. #define PMD_SIZE (1UL << PMD_SHIFT)
  86. #define PMD_MASK (~(PMD_SIZE-1))
  87. /* PGDIR_SHIFT determines what a third-level page table entry can map */
  88. #define PGDIR_SHIFT PMD_SHIFT
  89. #define PGDIR_SIZE (1UL << PGDIR_SHIFT)
  90. #define PGDIR_MASK (~(PGDIR_SIZE-1))
  91. /*
  92.  * Entries per page directory level: we use two-level, so
  93.  * we don't really have any PMD directory physically.
  94.  */
  95. #ifdef CONFIG_64BIT_PHYS_ADDR
  96. #define PTRS_PER_PTE 512
  97. #define PTRS_PER_PMD 1
  98. #define PTRS_PER_PGD 2048
  99. #define PGD_ORDER 1
  100. #else
  101. #define PTRS_PER_PTE 1024
  102. #define PTRS_PER_PMD 1
  103. #define PTRS_PER_PGD 1024
  104. #define PGD_ORDER 0
  105. #endif
  106. #define USER_PTRS_PER_PGD (0x80000000UL/PGDIR_SIZE)
  107. #define FIRST_USER_PGD_NR 0
  108. #define VMALLOC_START     KSEG2
  109. #define VMALLOC_VMADDR(x) ((unsigned long)(x))
  110. #if CONFIG_HIGHMEM
  111. # define VMALLOC_END (PKMAP_BASE-2*PAGE_SIZE)
  112. #else
  113. # define VMALLOC_END (FIXADDR_START-2*PAGE_SIZE)
  114. #endif
  115. #include <asm/pgtable-bits.h>
  116. #define PAGE_NONE __pgprot(_PAGE_PRESENT | _CACHE_CACHABLE_NONCOHERENT)
  117. #define PAGE_SHARED     __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | 
  118. PAGE_CACHABLE_DEFAULT)
  119. #define PAGE_COPY       __pgprot(_PAGE_PRESENT | _PAGE_READ | 
  120. PAGE_CACHABLE_DEFAULT)
  121. #define PAGE_READONLY   __pgprot(_PAGE_PRESENT | _PAGE_READ | 
  122. PAGE_CACHABLE_DEFAULT)
  123. #define PAGE_KERNEL __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | 
  124. _PAGE_GLOBAL | PAGE_CACHABLE_DEFAULT)
  125. #define PAGE_USERIO     __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | 
  126. PAGE_CACHABLE_DEFAULT)
  127. #define PAGE_KERNEL_UNCACHED __pgprot(_PAGE_PRESENT | __READABLE | 
  128. __WRITEABLE | _PAGE_GLOBAL | _CACHE_UNCACHED)
  129. /*
  130.  * MIPS can't do page protection for execute, and considers that the same like
  131.  * read. Also, write permissions imply read permissions. This is the closest
  132.  * we can get by reasonable means..
  133.  */
  134. #define __P000 PAGE_NONE
  135. #define __P001 PAGE_READONLY
  136. #define __P010 PAGE_COPY
  137. #define __P011 PAGE_COPY
  138. #define __P100 PAGE_READONLY
  139. #define __P101 PAGE_READONLY
  140. #define __P110 PAGE_COPY
  141. #define __P111 PAGE_COPY
  142. #define __S000 PAGE_NONE
  143. #define __S001 PAGE_READONLY
  144. #define __S010 PAGE_SHARED
  145. #define __S011 PAGE_SHARED
  146. #define __S100 PAGE_READONLY
  147. #define __S101 PAGE_READONLY
  148. #define __S110 PAGE_SHARED
  149. #define __S111 PAGE_SHARED
  150. #ifdef CONFIG_64BIT_PHYS_ADDR
  151. #define pte_ERROR(e) 
  152. printk("%s:%d: bad pte %016Lx.n", __FILE__, __LINE__, pte_val(e))
  153. #else
  154. #define pte_ERROR(e) 
  155. printk("%s:%d: bad pte %08lx.n", __FILE__, __LINE__, pte_val(e))
  156. #endif
  157. #define pmd_ERROR(e) 
  158. printk("%s:%d: bad pmd %08lx.n", __FILE__, __LINE__, pmd_val(e))
  159. #define pgd_ERROR(e) 
  160. printk("%s:%d: bad pgd %08lx.n", __FILE__, __LINE__, pgd_val(e))
  161. extern unsigned long empty_zero_page;
  162. extern unsigned long zero_page_mask;
  163. #define ZERO_PAGE(vaddr) 
  164. (virt_to_page(empty_zero_page + (((unsigned long)(vaddr)) & zero_page_mask)))
  165. extern void load_pgd(unsigned long pg_dir);
  166. extern pmd_t invalid_pte_table[PAGE_SIZE/sizeof(pmd_t)];
  167. /*
  168.  * Conversion functions: convert a page and protection to a page entry,
  169.  * and a page entry and page directory to the page they refer to.
  170.  */
  171. static inline unsigned long pmd_page(pmd_t pmd)
  172. {
  173. return pmd_val(pmd);
  174. }
  175. static inline void pmd_set(pmd_t * pmdp, pte_t * ptep)
  176. {
  177. pmd_val(*pmdp) = (((unsigned long) ptep) & PAGE_MASK);
  178. }
  179. static inline int pte_none(pte_t pte)    { return !(pte_val(pte) & ~_PAGE_GLOBAL); }
  180. static inline int pte_present(pte_t pte) { return pte_val(pte) & _PAGE_PRESENT; }
  181. /* Certain architectures need to do special things when pte's
  182.  * within a page table are directly modified.  Thus, the following
  183.  * hook is made available.
  184.  */
  185. static inline void set_pte(pte_t *ptep, pte_t pteval)
  186. {
  187. *ptep = pteval;
  188. #if !defined(CONFIG_CPU_R3000) && !defined(CONFIG_CPU_TX39XX)
  189. if (pte_val(pteval) & _PAGE_GLOBAL) {
  190. pte_t *buddy = ptep_buddy(ptep);
  191. /*
  192.  * Make sure the buddy is global too (if it's !none,
  193.  * it better already be global)
  194.  */
  195. if (pte_none(*buddy))
  196. pte_val(*buddy) = pte_val(*buddy) | _PAGE_GLOBAL;
  197. }
  198. #endif
  199. }
  200. static inline void pte_clear(pte_t *ptep)
  201. {
  202. #if !defined(CONFIG_CPU_R3000) && !defined(CONFIG_CPU_TX39XX)
  203. /* Preserve global status for the pair */
  204. if (pte_val(*ptep_buddy(ptep)) & _PAGE_GLOBAL)
  205. set_pte(ptep, __pte(_PAGE_GLOBAL));
  206. else
  207. #endif
  208. set_pte(ptep, __pte(0));
  209. }
  210. /*
  211.  * (pmds are folded into pgds so this doesn't get actually called,
  212.  * but the define is needed for a generic inline function.)
  213.  */
  214. #define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval)
  215. #define set_pgd(pgdptr, pgdval) (*(pgdptr) = pgdval)
  216. /*
  217.  * Empty pgd/pmd entries point to the invalid_pte_table.
  218.  */
  219. static inline int pmd_none(pmd_t pmd)
  220. {
  221. return pmd_val(pmd) == (unsigned long) invalid_pte_table;
  222. }
  223. static inline int pmd_bad(pmd_t pmd)
  224. {
  225. return ((pmd_page(pmd) > (unsigned long) high_memory) ||
  226.         (pmd_page(pmd) < PAGE_OFFSET));
  227. }
  228. static inline int pmd_present(pmd_t pmd)
  229. {
  230. return (pmd_val(pmd) != (unsigned long) invalid_pte_table);
  231. }
  232. static inline void pmd_clear(pmd_t *pmdp)
  233. {
  234. pmd_val(*pmdp) = ((unsigned long) invalid_pte_table);
  235. }
  236. /*
  237.  * The "pgd_xxx()" functions here are trivial for a folded two-level
  238.  * setup: the pgd is never bad, and a pmd always exists (as it's folded
  239.  * into the pgd entry)
  240.  */
  241. static inline int pgd_none(pgd_t pgd) { return 0; }
  242. static inline int pgd_bad(pgd_t pgd) { return 0; }
  243. static inline int pgd_present(pgd_t pgd) { return 1; }
  244. static inline void pgd_clear(pgd_t *pgdp) { }
  245. /*
  246.  * Permanent address of a page.  Obviously must never be called on a highmem
  247.  * page.
  248.  */
  249. #ifdef CONFIG_CPU_VR41XX
  250. #define pte_page(x)             (mem_map+(unsigned long)((pte_val(x) >> (PAGE_SHIFT + 2))))
  251. #else
  252. #define pte_page(x) (mem_map+(unsigned long)((pte_val(x) >> PAGE_SHIFT)))
  253. #endif
  254. /*
  255.  * The following only work if pte_present() is true.
  256.  * Undefined behaviour if not..
  257.  */
  258. static inline int pte_read(pte_t pte) { return pte_val(pte) & _PAGE_READ; }
  259. static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_WRITE; }
  260. static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_MODIFIED; }
  261. static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
  262. static inline pte_t pte_wrprotect(pte_t pte)
  263. {
  264. pte_val(pte) &= ~(_PAGE_WRITE | _PAGE_SILENT_WRITE);
  265. return pte;
  266. }
  267. static inline pte_t pte_rdprotect(pte_t pte)
  268. {
  269. pte_val(pte) &= ~(_PAGE_READ | _PAGE_SILENT_READ);
  270. return pte;
  271. }
  272. static inline pte_t pte_mkclean(pte_t pte)
  273. {
  274. pte_val(pte) &= ~(_PAGE_MODIFIED|_PAGE_SILENT_WRITE);
  275. return pte;
  276. }
  277. static inline pte_t pte_mkold(pte_t pte)
  278. {
  279. pte_val(pte) &= ~(_PAGE_ACCESSED|_PAGE_SILENT_READ);
  280. return pte;
  281. }
  282. static inline pte_t pte_mkwrite(pte_t pte)
  283. {
  284. pte_val(pte) |= _PAGE_WRITE;
  285. if (pte_val(pte) & _PAGE_MODIFIED)
  286. pte_val(pte) |= _PAGE_SILENT_WRITE;
  287. return pte;
  288. }
  289. static inline pte_t pte_mkread(pte_t pte)
  290. {
  291. pte_val(pte) |= _PAGE_READ;
  292. if (pte_val(pte) & _PAGE_ACCESSED)
  293. pte_val(pte) |= _PAGE_SILENT_READ;
  294. return pte;
  295. }
  296. static inline pte_t pte_mkdirty(pte_t pte)
  297. {
  298. pte_val(pte) |= _PAGE_MODIFIED;
  299. if (pte_val(pte) & _PAGE_WRITE)
  300. pte_val(pte) |= _PAGE_SILENT_WRITE;
  301. return pte;
  302. }
  303. /*
  304.  * Macro to make mark a page protection value as "uncacheable".  Note
  305.  * that "protection" is really a misnomer here as the protection value
  306.  * contains the memory attribute bits, dirty bits, and various other
  307.  * bits as well.
  308.  */
  309. #define pgprot_noncached pgprot_noncached
  310. static inline pgprot_t pgprot_noncached(pgprot_t _prot)
  311. {
  312. unsigned long prot = pgprot_val(_prot);
  313. prot = (prot & ~_CACHE_MASK) | _CACHE_UNCACHED;
  314. return __pgprot(prot);
  315. }
  316. static inline pte_t pte_mkyoung(pte_t pte)
  317. {
  318. pte_val(pte) |= _PAGE_ACCESSED;
  319. if (pte_val(pte) & _PAGE_READ)
  320. pte_val(pte) |= _PAGE_SILENT_READ;
  321. return pte;
  322. }
  323. /*
  324.  * Conversion functions: convert a page and protection to a page entry,
  325.  * and a page entry and page directory to the page they refer to.
  326.  */
  327. #ifdef CONFIG_CPU_VR41XX
  328. #define mk_pte(page, pgprot)                                            
  329. ({                                                                      
  330.         pte_t   __pte;                                                  
  331.                                                                         
  332.         pte_val(__pte) = ((phys_t)(page - mem_map) << (PAGE_SHIFT + 2)) | 
  333.                          pgprot_val(pgprot);                            
  334.                                                                         
  335.         __pte;                                                          
  336. })
  337. #else
  338. #define mk_pte(page, pgprot)
  339. ({
  340. pte_t   __pte;
  341. pte_val(__pte) = ((phys_t)(page - mem_map) << PAGE_SHIFT) | 
  342.                  pgprot_val(pgprot);
  343. __pte;
  344. })
  345. #endif
  346. static inline pte_t mk_pte_phys(phys_t physpage, pgprot_t pgprot)
  347. {
  348. #ifdef CONFIG_CPU_VR41XX
  349.         return __pte((physpage << 2) | pgprot_val(pgprot));
  350. #else
  351. return __pte(physpage | pgprot_val(pgprot));
  352. #endif
  353. }
  354. static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
  355. {
  356. return __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot));
  357. }
  358. #define page_pte(page) page_pte_prot(page, __pgprot(0))
  359. #define __pgd_offset(address) pgd_index(address)
  360. #define __pmd_offset(address) 
  361. (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
  362. /* to find an entry in a kernel page-table-directory */
  363. #define pgd_offset_k(address) pgd_offset(&init_mm, address)
  364. #define pgd_index(address) ((address) >> PGDIR_SHIFT)
  365. /* to find an entry in a page-table-directory */
  366. static inline pgd_t *pgd_offset(struct mm_struct *mm, unsigned long address)
  367. {
  368. return mm->pgd + pgd_index(address);
  369. }
  370. /* Find an entry in the second-level page table.. */
  371. static inline pmd_t *pmd_offset(pgd_t *dir, unsigned long address)
  372. {
  373. return (pmd_t *) dir;
  374. }
  375. /* Find an entry in the third-level page table.. */
  376. static inline pte_t *pte_offset(pmd_t * dir, unsigned long address)
  377. {
  378. return (pte_t *) (pmd_page(*dir)) +
  379.        ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1));
  380. }
  381. extern int do_check_pgt_cache(int, int);
  382. extern pgd_t swapper_pg_dir[1024];
  383. extern void paging_init(void);
  384. extern void update_mmu_cache(struct vm_area_struct *vma,
  385. unsigned long address, pte_t pte);
  386. /* Swap entries must have VALID and GLOBAL bits cleared. */
  387. #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
  388. #define SWP_TYPE(x) (((x).val >> 1) & 0x7f)
  389. #define SWP_OFFSET(x) ((x).val >> 10)
  390. #define SWP_ENTRY(type,offset) ((swp_entry_t) { ((type) << 1) | ((offset) << 10) })
  391. #else
  392. #define SWP_TYPE(x) (((x).val >> 1) & 0x1f)
  393. #define SWP_OFFSET(x) ((x).val >> 8)
  394. #define SWP_ENTRY(type,offset) ((swp_entry_t) { ((type) << 1) | ((offset) << 8) })
  395. #endif
  396. #define pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
  397. #define swp_entry_to_pte(x) ((pte_t) { (x).val })
  398. /* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
  399. #define PageSkip(page) (0)
  400. #define kern_addr_valid(addr) (1)
  401. #include <asm-generic/pgtable.h>
  402. /*
  403.  * We provide our own get_unmapped area to cope with the virtual aliasing
  404.  * constraints placed on us by the cache architecture.
  405.  */
  406. #define HAVE_ARCH_UNMAPPED_AREA
  407. #define io_remap_page_range remap_page_range
  408. /*
  409.  * No page table caches to initialise
  410.  */
  411. #define pgtable_cache_init() do { } while (0)
  412. #endif /* _ASM_PGTABLE_H */