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

Linux/Unix编程

开发平台:

Unix_Linux

  1. #ifndef _PPC64_PGTABLE_H
  2. #define _PPC64_PGTABLE_H
  3. /*
  4.  * This file contains the functions and defines necessary to modify and use
  5.  * the ppc64 hashed page table.
  6.  */
  7. #ifndef __ASSEMBLY__
  8. #include <asm/processor.h> /* For TASK_SIZE */
  9. #include <asm/mmu.h>
  10. #include <asm/page.h>
  11. #endif /* __ASSEMBLY__ */
  12. /* PMD_SHIFT determines what a second-level page table entry can map */
  13. #define PMD_SHIFT (PAGE_SHIFT + PAGE_SHIFT - 3)
  14. #define PMD_SIZE (1UL << PMD_SHIFT)
  15. #define PMD_MASK (~(PMD_SIZE-1))
  16. /* PGDIR_SHIFT determines what a third-level page table entry can map */
  17. #define PGDIR_SHIFT (PAGE_SHIFT + (PAGE_SHIFT - 3) + (PAGE_SHIFT - 2))
  18. #define PGDIR_SIZE (1UL << PGDIR_SHIFT)
  19. #define PGDIR_MASK (~(PGDIR_SIZE-1))
  20. /*
  21.  * Entries per page directory level.  The PTE level must use a 64b record
  22.  * for each page table entry.  The PMD and PGD level use a 32b record for 
  23.  * each entry by assuming that each entry is page aligned.
  24.  */
  25. #define PTE_INDEX_SIZE  9
  26. #define PMD_INDEX_SIZE  10
  27. #define PGD_INDEX_SIZE  10
  28. #define PTRS_PER_PTE (1 << PTE_INDEX_SIZE)
  29. #define PTRS_PER_PMD (1 << PMD_INDEX_SIZE)
  30. #define PTRS_PER_PGD (1 << PGD_INDEX_SIZE)
  31. #if 0
  32. /* DRENG / PPPBBB This is a compiler bug!!! */
  33. #define USER_PTRS_PER_PGD (TASK_SIZE / PGDIR_SIZE)
  34. #else
  35. #define USER_PTRS_PER_PGD (1024)
  36. #endif
  37. #define FIRST_USER_PGD_NR 0
  38. #define EADDR_SIZE (PTE_INDEX_SIZE + PMD_INDEX_SIZE + 
  39.                     PGD_INDEX_SIZE + PAGE_SHIFT) 
  40. /*
  41.  * Define the address range of the vmalloc VM area.
  42.  */
  43. #define VMALLOC_START (0xD000000000000000)
  44. #define VMALLOC_VMADDR(x) ((unsigned long)(x))
  45. #define VMALLOC_END   (VMALLOC_START + VALID_EA_BITS)
  46. /*
  47.  * Define the address range of the imalloc VM area.
  48.  * (used for ioremap)
  49.  */
  50. #define IMALLOC_START (ioremap_bot)
  51. #define IMALLOC_VMADDR(x) ((unsigned long)(x))
  52. #define IMALLOC_BASE  (0xE000000000000000)
  53. #define IMALLOC_END   (IMALLOC_BASE + VALID_EA_BITS)
  54. /*
  55.  * Define the address range mapped virt <-> physical
  56.  */
  57. #define KRANGE_START KERNELBASE
  58. #define KRANGE_END   (KRANGE_START + VALID_EA_BITS)
  59. /*
  60.  * Define the user address range
  61.  */
  62. #define USER_START (0UL)
  63. #define USER_END   (USER_START + VALID_EA_BITS)
  64. /*
  65.  * Bits in a linux-style PTE.  These match the bits in the
  66.  * (hardware-defined) PowerPC PTE as closely as possible.
  67.  */
  68. #define _PAGE_PRESENT 0x001UL /* software: pte contains a translation */
  69. #define _PAGE_USER 0x002UL /* matches one of the PP bits */
  70. #define _PAGE_RW 0x004UL /* software: user write access allowed */
  71. #define _PAGE_GUARDED 0x008UL
  72. #define _PAGE_COHERENT 0x010UL /* M: enforce memory coherence (SMP systems) */
  73. #define _PAGE_NO_CACHE 0x020UL /* I: cache inhibit */
  74. #define _PAGE_WRITETHRU 0x040UL /* W: cache write-through */
  75. #define _PAGE_DIRTY 0x080UL /* C: page changed */
  76. #define _PAGE_ACCESSED 0x100UL /* R: page referenced */
  77. #define _PAGE_HPTENOIX 0x200UL /* software: pte HPTE slot unknown */
  78. #define _PAGE_HASHPTE 0x400UL /* software: pte has an associated HPTE */
  79. #define _PAGE_EXEC 0x800UL /* software: i-cache coherence required */
  80. #define _PAGE_SECONDARY 0x8000UL /* software: HPTE is in secondary group */
  81. #define _PAGE_GROUP_IX  0x7000UL /* software: HPTE index within group */
  82. /* Bits 0x7000 identify the index within an HPT Group */
  83. #define _PAGE_HPTEFLAGS (_PAGE_HASHPTE | _PAGE_HPTENOIX | _PAGE_SECONDARY | _PAGE_GROUP_IX)
  84. /* PAGE_MASK gives the right answer below, but only by accident */
  85. /* It should be preserving the high 48 bits and then specifically */
  86. /* preserving _PAGE_SECONDARY | _PAGE_GROUP_IX */
  87. #define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_HPTEFLAGS)
  88. #define _PAGE_BASE _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_COHERENT
  89. #define _PAGE_WRENABLE _PAGE_RW | _PAGE_DIRTY 
  90. /* __pgprot defined in asm-ppc64/page.h */
  91. #define PAGE_NONE __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
  92. #define PAGE_SHARED __pgprot(_PAGE_BASE | _PAGE_RW | _PAGE_USER)
  93. #define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_RW | _PAGE_USER | _PAGE_EXEC)
  94. #define PAGE_COPY __pgprot(_PAGE_BASE | _PAGE_USER)
  95. #define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
  96. #define PAGE_READONLY __pgprot(_PAGE_BASE | _PAGE_USER)
  97. #define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
  98. #define PAGE_KERNEL __pgprot(_PAGE_BASE | _PAGE_WRENABLE)
  99. #define PAGE_KERNEL_CI __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | 
  100.        _PAGE_WRENABLE | _PAGE_NO_CACHE | _PAGE_GUARDED)
  101. /*
  102.  * The PowerPC can only do execute protection on a segment (256MB) basis,
  103.  * not on a page basis.  So we consider execute permission the same as read.
  104.  * Also, write permissions imply read permissions.
  105.  * This is the closest we can get..
  106.  */
  107. #define __P000 PAGE_NONE
  108. #define __P001 PAGE_READONLY_X
  109. #define __P010 PAGE_COPY
  110. #define __P011 PAGE_COPY_X
  111. #define __P100 PAGE_READONLY
  112. #define __P101 PAGE_READONLY_X
  113. #define __P110 PAGE_COPY
  114. #define __P111 PAGE_COPY_X
  115. #define __S000 PAGE_NONE
  116. #define __S001 PAGE_READONLY_X
  117. #define __S010 PAGE_SHARED
  118. #define __S011 PAGE_SHARED_X
  119. #define __S100 PAGE_READONLY
  120. #define __S101 PAGE_READONLY_X
  121. #define __S110 PAGE_SHARED
  122. #define __S111 PAGE_SHARED_X
  123. #ifndef __ASSEMBLY__
  124. /*
  125.  * ZERO_PAGE is a global shared page that is always zero: used
  126.  * for zero-mapped memory areas etc..
  127.  */
  128. extern unsigned long empty_zero_page[PAGE_SIZE/sizeof(unsigned long)];
  129. #define ZERO_PAGE(vaddr) (mem_map + MAP_NR(empty_zero_page))
  130. #endif /* __ASSEMBLY__ */
  131. /* shift to put page number into pte */
  132. #define PTE_SHIFT (16)
  133. #ifndef __ASSEMBLY__
  134. /*
  135.  * Conversion functions: convert a page and protection to a page entry,
  136.  * and a page entry and page directory to the page they refer to.
  137.  *
  138.  * mk_pte_phys takes a physical address as input 
  139.  *
  140.  * mk_pte takes a (struct page *) as input
  141.  */
  142. #define mk_pte_phys(physpage,pgprot)                                      
  143. ({   
  144. pte_t pte;   
  145. pte_val(pte) = (((physpage)<<(PTE_SHIFT-PAGE_SHIFT)) | pgprot_val(pgprot)); 
  146. pte;           
  147. })
  148. #define mk_pte(page,pgprot)                                               
  149. ({   
  150. pte_t pte;   
  151. pte_val(pte) = ((unsigned long)((page) - mem_map) << PTE_SHIFT) |   
  152.                         pgprot_val(pgprot);                               
  153. pte;           
  154. })
  155. #define pte_modify(_pte, newprot) 
  156.   (__pte((pte_val(_pte) & _PAGE_CHG_MASK) | pgprot_val(newprot)))
  157. #define pte_none(pte) ((pte_val(pte) & ~_PAGE_HPTEFLAGS) == 0)
  158. #define pte_present(pte) (pte_val(pte) & _PAGE_PRESENT)
  159. /* pte_clear moved to later in this file */
  160. #define pte_pagenr(x) ((unsigned long)((pte_val(x) >> PTE_SHIFT)))
  161. #define pte_page(x) (mem_map+pte_pagenr(x))
  162. #define pmd_set(pmdp, ptep)  (pmd_val(*(pmdp)) = (__ba_to_bpn(ptep)))
  163. #define pmd_none(pmd) (!pmd_val(pmd))
  164. #define pmd_bad(pmd) ((pmd_val(pmd)) == 0)
  165. #define pmd_present(pmd) ((pmd_val(pmd)) != 0)
  166. #define pmd_clear(pmdp) (pmd_val(*(pmdp)) = 0)
  167. #define pmd_page(pmd) (__bpn_to_ba(pmd_val(pmd)))
  168. #define pgd_set(pgdp, pmdp) (pgd_val(*(pgdp)) = (__ba_to_bpn(pmdp)))
  169. #define pgd_none(pgd) (!pgd_val(pgd))
  170. #define pgd_bad(pgd) ((pgd_val(pgd)) == 0)
  171. #define pgd_present(pgd) (pgd_val(pgd) != 0UL)
  172. #define pgd_clear(pgdp) (pgd_val(*(pgdp)) = 0UL)
  173. #define pgd_page(pgd) (__bpn_to_ba(pgd_val(pgd))) 
  174. /* 
  175.  * Find an entry in a page-table-directory.  We combine the address region 
  176.  * (the high order N bits) and the pgd portion of the address.
  177.  */
  178. #define pgd_index(address) (((address) >> (PGDIR_SHIFT)) & (PTRS_PER_PGD -1))
  179. #define pgd_offset(mm, address)  ((mm)->pgd + pgd_index(address))
  180. /* Find an entry in the second-level page table.. */
  181. #define pmd_offset(dir,addr) 
  182.   ((pmd_t *) pgd_page(*(dir)) + (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1)))
  183. /* Find an entry in the third-level page table.. */
  184. #define pte_offset(dir,addr) 
  185.   ((pte_t *) pmd_page(*(dir)) + (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)))
  186. /* to find an entry in a kernel page-table-directory */
  187. /* This now only contains the vmalloc pages */
  188. #define pgd_offset_k(address) pgd_offset(&init_mm, address)
  189. /* to find an entry in the ioremap page-table-directory */
  190. #define pgd_offset_i(address) (ioremap_pgd + pgd_index(address))
  191. #define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
  192. /*
  193.  * The following only work if pte_present() is true.
  194.  * Undefined behaviour if not..
  195.  */
  196. static inline int pte_read(pte_t pte)  { return pte_val(pte) & _PAGE_USER;}
  197. static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW;}
  198. static inline int pte_exec(pte_t pte)  { return pte_val(pte) & _PAGE_EXEC;}
  199. static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY;}
  200. static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED;}
  201. static inline void pte_uncache(pte_t pte) { pte_val(pte) |= _PAGE_NO_CACHE; }
  202. static inline void pte_cache(pte_t pte)   { pte_val(pte) &= ~_PAGE_NO_CACHE; }
  203. static inline pte_t pte_rdprotect(pte_t pte) {
  204. pte_val(pte) &= ~_PAGE_USER; return pte; }
  205. static inline pte_t pte_exprotect(pte_t pte) {
  206. pte_val(pte) &= ~_PAGE_EXEC; return pte; }
  207. static inline pte_t pte_wrprotect(pte_t pte) {
  208. pte_val(pte) &= ~(_PAGE_RW); return pte; }
  209. static inline pte_t pte_mkclean(pte_t pte) {
  210. pte_val(pte) &= ~(_PAGE_DIRTY); return pte; }
  211. static inline pte_t pte_mkold(pte_t pte) {
  212. pte_val(pte) &= ~_PAGE_ACCESSED; return pte; }
  213. static inline pte_t pte_mkread(pte_t pte) {
  214. pte_val(pte) |= _PAGE_USER; return pte; }
  215. static inline pte_t pte_mkexec(pte_t pte) {
  216. pte_val(pte) |= _PAGE_USER | _PAGE_EXEC; return pte; }
  217. static inline pte_t pte_mkwrite(pte_t pte) {
  218. pte_val(pte) |= _PAGE_RW; return pte; }
  219. static inline pte_t pte_mkdirty(pte_t pte) {
  220. pte_val(pte) |= _PAGE_DIRTY; return pte; }
  221. static inline pte_t pte_mkyoung(pte_t pte) {
  222. pte_val(pte) |= _PAGE_ACCESSED; return pte; }
  223. /* Atomic PTE updates */
  224. static inline unsigned long pte_update( pte_t *p, unsigned long clr,
  225. unsigned long set )
  226. {
  227. unsigned long old, tmp;
  228. __asm__ __volatile__("n
  229. 1: ldarx %0,0,%3 n
  230. andc %1,%0,%4 n
  231. or %1,%1,%5 n
  232. stdcx. %1,0,%3 n
  233. bne- 1b"
  234. : "=&r" (old), "=&r" (tmp), "=m" (*p)
  235. : "r" (p), "r" (clr), "r" (set), "m" (*p)
  236. : "cc" );
  237. return old;
  238. }
  239. static inline int ptep_test_and_clear_young(pte_t *ptep)
  240. {
  241. return (pte_update(ptep, _PAGE_ACCESSED, 0) & _PAGE_ACCESSED) != 0;
  242. }
  243. static inline int ptep_test_and_clear_dirty(pte_t *ptep)
  244. {
  245. return (pte_update(ptep, _PAGE_DIRTY, 0) & _PAGE_DIRTY) != 0;
  246. }
  247. static inline pte_t ptep_get_and_clear(pte_t *ptep)
  248. {
  249. return __pte(pte_update(ptep, ~_PAGE_HPTEFLAGS, 0));
  250. }
  251. static inline void ptep_set_wrprotect(pte_t *ptep)
  252. {
  253. pte_update(ptep, _PAGE_RW, 0);
  254. }
  255. static inline void ptep_mkdirty(pte_t *ptep)
  256. {
  257. pte_update(ptep, 0, _PAGE_DIRTY);
  258. }
  259. #define pte_same(A,B) (((pte_val(A) ^ pte_val(B)) & ~_PAGE_HPTEFLAGS) == 0)
  260. /*
  261.  * set_pte stores a linux PTE into the linux page table.
  262.  * On machines which use an MMU hash table we avoid changing the
  263.  * _PAGE_HASHPTE bit.
  264.  */
  265. static inline void set_pte(pte_t *ptep, pte_t pte)
  266. {
  267. pte_update(ptep, ~_PAGE_HPTEFLAGS, pte_val(pte) & ~_PAGE_HPTEFLAGS);
  268. }
  269. static inline void pte_clear(pte_t * ptep)
  270. {
  271. pte_update(ptep, ~_PAGE_HPTEFLAGS, 0);
  272. }
  273. struct mm_struct;
  274. struct vm_area_struct;
  275. extern void local_flush_tlb_all(void);
  276. extern void local_flush_tlb_mm(struct mm_struct *mm);
  277. extern void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr);
  278. extern void local_flush_tlb_range(struct mm_struct *mm, unsigned long start,
  279.     unsigned long end);
  280. #define flush_tlb_all local_flush_tlb_all
  281. #define flush_tlb_mm local_flush_tlb_mm
  282. #define flush_tlb_page local_flush_tlb_page
  283. #define flush_tlb_range local_flush_tlb_range
  284. static inline void flush_tlb_pgtables(struct mm_struct *mm,
  285.       unsigned long start, unsigned long end)
  286. {
  287. /* PPC has hw page tables. */
  288. }
  289. /*
  290.  * No cache flushing is required when address mappings are
  291.  * changed, because the caches on PowerPCs are physically
  292.  * addressed.
  293.  */
  294. #define flush_cache_all() do { } while (0)
  295. #define flush_cache_mm(mm) do { } while (0)
  296. #define flush_cache_range(mm, a, b) do { } while (0)
  297. #define flush_cache_page(vma, p) do { } while (0)
  298. #define flush_page_to_ram(page) do { } while (0)
  299. extern void flush_icache_user_range(struct vm_area_struct *vma,
  300. struct page *page, unsigned long addr, int len);
  301. extern void flush_icache_range(unsigned long, unsigned long);
  302. extern void __flush_dcache_icache(void *page_va);
  303. extern void flush_dcache_page(struct page *page);
  304. extern void flush_icache_page(struct vm_area_struct *vma, struct page *page);
  305. extern unsigned long va_to_phys(unsigned long address);
  306. extern pte_t *va_to_pte(unsigned long address);
  307. extern unsigned long ioremap_bot, ioremap_base;
  308. #define USER_PGD_PTRS (PAGE_OFFSET >> PGDIR_SHIFT)
  309. #define KERNEL_PGD_PTRS (PTRS_PER_PGD-USER_PGD_PTRS)
  310. #define pte_ERROR(e) 
  311. printk("%s:%d: bad pte %016lx.n", __FILE__, __LINE__, pte_val(e))
  312. #define pmd_ERROR(e) 
  313. printk("%s:%d: bad pmd %08x.n", __FILE__, __LINE__, pmd_val(e))
  314. #define pgd_ERROR(e) 
  315. printk("%s:%d: bad pgd %08x.n", __FILE__, __LINE__, pgd_val(e))
  316. extern pgd_t swapper_pg_dir[1024];
  317. extern pgd_t ioremap_dir[1024];
  318. extern void paging_init(void);
  319. /*
  320.  * Page tables may have changed.  We don't need to do anything here
  321.  * as entries are faulted into the hash table by the low-level
  322.  * data/instruction access exception handlers.
  323.  */
  324. /*
  325.  * We won't be able to use update_mmu_cache to update the 
  326.  * hardware page table because we need to update the pte
  327.  * as well, but we don't get the address of the pte, only
  328.  * its value.
  329.  */
  330. #define update_mmu_cache(vma, addr, pte) do { } while (0)
  331. extern void flush_hash_segments(unsigned low_vsid, unsigned high_vsid);
  332. extern void flush_hash_page(unsigned long context, unsigned long ea, pte_t *ptep);
  333. extern void build_valid_hpte(unsigned long vsid, unsigned long ea, 
  334.      unsigned long pa, pte_t * ptep, 
  335.      unsigned hpteflags, unsigned bolted );
  336. /* Encode and de-code a swap entry */
  337. #define SWP_TYPE(entry) (((entry).val >> 1) & 0x3f)
  338. #define SWP_OFFSET(entry) ((entry).val >> 8)
  339. #define SWP_ENTRY(type, offset) ((swp_entry_t) { ((type) << 1) | ((offset) << 8) })
  340. #define pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) >> PTE_SHIFT })
  341. #define swp_entry_to_pte(x) ((pte_t) { (x).val << PTE_SHIFT })
  342. /*
  343.  * kern_addr_valid is intended to indicate whether an address is a valid
  344.  * kernel address.  Most 32-bit archs define it as always true (like this)
  345.  * but most 64-bit archs actually perform a test.  What should we do here?
  346.  * The only use is in fs/ncpfs/dir.c
  347.  */
  348. #define kern_addr_valid(addr) (1)
  349. #define io_remap_page_range remap_page_range 
  350. /*
  351.  * No page table caches to initialise
  352.  */
  353. #define pgtable_cache_init() do { } while (0)
  354. extern void updateBoltedHptePP(unsigned long newpp, unsigned long ea);
  355. extern void hpte_init_pSeries(void);
  356. extern void hpte_init_iSeries(void);
  357. extern void make_pte(HPTE * htab, unsigned long va, unsigned long pa,
  358. int mode, unsigned long hash_mask, int large);
  359. #endif /* __ASSEMBLY__ */
  360. #endif /* _PPC64_PGTABLE_H */