home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / src / linux-headers-2.6.17-6 / include / asm-mips / pgtable.h < prev    next >
Encoding:
C/C++ Source or Header  |  2006-08-11  |  11.3 KB  |  420 lines

  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) 2003 Ralf Baechle
  7.  */
  8. #ifndef _ASM_PGTABLE_H
  9. #define _ASM_PGTABLE_H
  10.  
  11. #ifdef CONFIG_32BIT
  12. #include <asm/pgtable-32.h>
  13. #endif
  14. #ifdef CONFIG_64BIT
  15. #include <asm/pgtable-64.h>
  16. #endif
  17.  
  18. #include <asm/io.h>
  19. #include <asm/pgtable-bits.h>
  20.  
  21. struct mm_struct;
  22. struct vm_area_struct;
  23.  
  24. #define PAGE_NONE    __pgprot(_PAGE_PRESENT | _CACHE_CACHABLE_NONCOHERENT)
  25. #define PAGE_SHARED    __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \
  26.             PAGE_CACHABLE_DEFAULT)
  27. #define PAGE_COPY    __pgprot(_PAGE_PRESENT | _PAGE_READ | \
  28.             PAGE_CACHABLE_DEFAULT)
  29. #define PAGE_READONLY    __pgprot(_PAGE_PRESENT | _PAGE_READ | \
  30.             PAGE_CACHABLE_DEFAULT)
  31. #define PAGE_KERNEL    __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
  32.             _PAGE_GLOBAL | PAGE_CACHABLE_DEFAULT)
  33. #define PAGE_USERIO    __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \
  34.             PAGE_CACHABLE_DEFAULT)
  35. #define PAGE_KERNEL_UNCACHED __pgprot(_PAGE_PRESENT | __READABLE | \
  36.             __WRITEABLE | _PAGE_GLOBAL | _CACHE_UNCACHED)
  37.  
  38. /*
  39.  * MIPS can't do page protection for execute, and considers that the same like
  40.  * read. Also, write permissions imply read permissions. This is the closest
  41.  * we can get by reasonable means..
  42.  */
  43. #define __P000    PAGE_NONE
  44. #define __P001    PAGE_READONLY
  45. #define __P010    PAGE_COPY
  46. #define __P011    PAGE_COPY
  47. #define __P100    PAGE_READONLY
  48. #define __P101    PAGE_READONLY
  49. #define __P110    PAGE_COPY
  50. #define __P111    PAGE_COPY
  51.  
  52. #define __S000    PAGE_NONE
  53. #define __S001    PAGE_READONLY
  54. #define __S010    PAGE_SHARED
  55. #define __S011    PAGE_SHARED
  56. #define __S100    PAGE_READONLY
  57. #define __S101    PAGE_READONLY
  58. #define __S110    PAGE_SHARED
  59. #define __S111    PAGE_SHARED
  60.  
  61. /*
  62.  * ZERO_PAGE is a global shared page that is always zero; used
  63.  * for zero-mapped memory areas etc..
  64.  */
  65.  
  66. extern unsigned long empty_zero_page;
  67. extern unsigned long zero_page_mask;
  68.  
  69. #define ZERO_PAGE(vaddr) \
  70.     (virt_to_page(empty_zero_page + (((unsigned long)(vaddr)) & zero_page_mask)))
  71.  
  72. #define __HAVE_ARCH_MOVE_PTE
  73. #define move_pte(pte, prot, old_addr, new_addr)                \
  74. ({                                    \
  75.      pte_t newpte = (pte);                        \
  76.     if (pte_present(pte) && pfn_valid(pte_pfn(pte)) &&        \
  77.             pte_page(pte) == ZERO_PAGE(old_addr))        \
  78.         newpte = mk_pte(ZERO_PAGE(new_addr), (prot));        \
  79.     newpte;                                \
  80. })
  81.  
  82. extern void paging_init(void);
  83.  
  84. /*
  85.  * Conversion functions: convert a page and protection to a page entry,
  86.  * and a page entry and page directory to the page they refer to.
  87.  */
  88. #define pmd_phys(pmd)        (pmd_val(pmd) - PAGE_OFFSET)
  89. #define pmd_page(pmd)        (pfn_to_page(pmd_phys(pmd) >> PAGE_SHIFT))
  90. #define pmd_page_kernel(pmd)    pmd_val(pmd)
  91.  
  92. #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32_R1)
  93.  
  94. #define pte_none(pte)        (!(((pte).pte_low | (pte).pte_high) & ~_PAGE_GLOBAL))
  95. #define pte_present(pte)    ((pte).pte_low & _PAGE_PRESENT)
  96.  
  97. static inline void set_pte(pte_t *ptep, pte_t pte)
  98. {
  99.     ptep->pte_high = pte.pte_high;
  100.     smp_wmb();
  101.     ptep->pte_low = pte.pte_low;
  102.     //printk("pte_high %x pte_low %x\n", ptep->pte_high, ptep->pte_low);
  103.  
  104.     if (pte.pte_low & _PAGE_GLOBAL) {
  105.         pte_t *buddy = ptep_buddy(ptep);
  106.         /*
  107.          * Make sure the buddy is global too (if it's !none,
  108.          * it better already be global)
  109.          */
  110.         if (pte_none(*buddy)) {
  111.             buddy->pte_low  |= _PAGE_GLOBAL;
  112.             buddy->pte_high |= _PAGE_GLOBAL;
  113.         }
  114.     }
  115. }
  116. #define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval)
  117.  
  118. static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
  119. {
  120.     pte_t null = __pte(0);
  121.  
  122.     /* Preserve global status for the pair */
  123.     if (ptep_buddy(ptep)->pte_low & _PAGE_GLOBAL)
  124.         null.pte_low = null.pte_high = _PAGE_GLOBAL;
  125.  
  126.     set_pte_at(mm, addr, ptep, null);
  127. }
  128. #else
  129.  
  130. #define pte_none(pte)        (!(pte_val(pte) & ~_PAGE_GLOBAL))
  131. #define pte_present(pte)    (pte_val(pte) & _PAGE_PRESENT)
  132.  
  133. /*
  134.  * Certain architectures need to do special things when pte's
  135.  * within a page table are directly modified.  Thus, the following
  136.  * hook is made available.
  137.  */
  138. static inline void set_pte(pte_t *ptep, pte_t pteval)
  139. {
  140.     *ptep = pteval;
  141. #if !defined(CONFIG_CPU_R3000) && !defined(CONFIG_CPU_TX39XX)
  142.     if (pte_val(pteval) & _PAGE_GLOBAL) {
  143.         pte_t *buddy = ptep_buddy(ptep);
  144.         /*
  145.          * Make sure the buddy is global too (if it's !none,
  146.          * it better already be global)
  147.          */
  148.         if (pte_none(*buddy))
  149.             pte_val(*buddy) = pte_val(*buddy) | _PAGE_GLOBAL;
  150.     }
  151. #endif
  152. }
  153. #define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval)
  154.  
  155. static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
  156. {
  157. #if !defined(CONFIG_CPU_R3000) && !defined(CONFIG_CPU_TX39XX)
  158.     /* Preserve global status for the pair */
  159.     if (pte_val(*ptep_buddy(ptep)) & _PAGE_GLOBAL)
  160.         set_pte_at(mm, addr, ptep, __pte(_PAGE_GLOBAL));
  161.     else
  162. #endif
  163.         set_pte_at(mm, addr, ptep, __pte(0));
  164. }
  165. #endif
  166.  
  167. /*
  168.  * (pmds are folded into puds so this doesn't get actually called,
  169.  * but the define is needed for a generic inline function.)
  170.  */
  171. #define set_pmd(pmdptr, pmdval) do { *(pmdptr) = (pmdval); } while(0)
  172.  
  173. #ifdef CONFIG_64BIT
  174. /*
  175.  * (puds are folded into pgds so this doesn't get actually called,
  176.  * but the define is needed for a generic inline function.)
  177.  */
  178. #define set_pud(pudptr, pudval) do { *(pudptr) = (pudval); } while(0)
  179. #endif
  180.  
  181. #define PGD_T_LOG2    ffz(~sizeof(pgd_t))
  182. #define PMD_T_LOG2    ffz(~sizeof(pmd_t))
  183. #define PTE_T_LOG2    ffz(~sizeof(pte_t))
  184.  
  185. extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
  186.  
  187. /*
  188.  * The following only work if pte_present() is true.
  189.  * Undefined behaviour if not..
  190.  */
  191. static inline int pte_user(pte_t pte)    { BUG(); return 0; }
  192. #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32_R1)
  193. static inline int pte_read(pte_t pte)    { return pte.pte_low & _PAGE_READ; }
  194. static inline int pte_write(pte_t pte)    { return pte.pte_low & _PAGE_WRITE; }
  195. static inline int pte_dirty(pte_t pte)    { return pte.pte_low & _PAGE_MODIFIED; }
  196. static inline int pte_young(pte_t pte)    { return pte.pte_low & _PAGE_ACCESSED; }
  197. static inline int pte_file(pte_t pte)    { return pte.pte_low & _PAGE_FILE; }
  198.  
  199. static inline pte_t pte_wrprotect(pte_t pte)
  200. {
  201.     pte.pte_low  &= ~(_PAGE_WRITE | _PAGE_SILENT_WRITE);
  202.     pte.pte_high &= ~_PAGE_SILENT_WRITE;
  203.     return pte;
  204. }
  205.  
  206. static inline pte_t pte_rdprotect(pte_t pte)
  207. {
  208.     pte.pte_low  &= ~(_PAGE_READ | _PAGE_SILENT_READ);
  209.     pte.pte_high &= ~_PAGE_SILENT_READ;
  210.     return pte;
  211. }
  212.  
  213. static inline pte_t pte_mkclean(pte_t pte)
  214. {
  215.     pte.pte_low  &= ~(_PAGE_MODIFIED | _PAGE_SILENT_WRITE);
  216.     pte.pte_high &= ~_PAGE_SILENT_WRITE;
  217.     return pte;
  218. }
  219.  
  220. static inline pte_t pte_mkold(pte_t pte)
  221. {
  222.     pte.pte_low  &= ~(_PAGE_ACCESSED | _PAGE_SILENT_READ);
  223.     pte.pte_high &= ~_PAGE_SILENT_READ;
  224.     return pte;
  225. }
  226.  
  227. static inline pte_t pte_mkwrite(pte_t pte)
  228. {
  229.     pte.pte_low |= _PAGE_WRITE;
  230.     if (pte.pte_low & _PAGE_MODIFIED) {
  231.         pte.pte_low  |= _PAGE_SILENT_WRITE;
  232.         pte.pte_high |= _PAGE_SILENT_WRITE;
  233.     }
  234.     return pte;
  235. }
  236.  
  237. static inline pte_t pte_mkread(pte_t pte)
  238. {
  239.     pte.pte_low |= _PAGE_READ;
  240.     if (pte.pte_low & _PAGE_ACCESSED) {
  241.         pte.pte_low  |= _PAGE_SILENT_READ;
  242.         pte.pte_high |= _PAGE_SILENT_READ;
  243.     }
  244.     return pte;
  245. }
  246.  
  247. static inline pte_t pte_mkdirty(pte_t pte)
  248. {
  249.     pte.pte_low |= _PAGE_MODIFIED;
  250.     if (pte.pte_low & _PAGE_WRITE) {
  251.         pte.pte_low  |= _PAGE_SILENT_WRITE;
  252.         pte.pte_high |= _PAGE_SILENT_WRITE;
  253.     }
  254.     return pte;
  255. }
  256.  
  257. static inline pte_t pte_mkyoung(pte_t pte)
  258. {
  259.     pte.pte_low |= _PAGE_ACCESSED;
  260.     if (pte.pte_low & _PAGE_READ)
  261.         pte.pte_low  |= _PAGE_SILENT_READ;
  262.         pte.pte_high |= _PAGE_SILENT_READ;
  263.     return pte;
  264. }
  265. #else
  266. static inline int pte_read(pte_t pte)    { return pte_val(pte) & _PAGE_READ; }
  267. static inline int pte_write(pte_t pte)    { return pte_val(pte) & _PAGE_WRITE; }
  268. static inline int pte_dirty(pte_t pte)    { return pte_val(pte) & _PAGE_MODIFIED; }
  269. static inline int pte_young(pte_t pte)    { return pte_val(pte) & _PAGE_ACCESSED; }
  270. static inline int pte_file(pte_t pte)    { return pte_val(pte) & _PAGE_FILE; }
  271.  
  272. static inline pte_t pte_wrprotect(pte_t pte)
  273. {
  274.     pte_val(pte) &= ~(_PAGE_WRITE | _PAGE_SILENT_WRITE);
  275.     return pte;
  276. }
  277.  
  278. static inline pte_t pte_rdprotect(pte_t pte)
  279. {
  280.     pte_val(pte) &= ~(_PAGE_READ | _PAGE_SILENT_READ);
  281.     return pte;
  282. }
  283.  
  284. static inline pte_t pte_mkclean(pte_t pte)
  285. {
  286.     pte_val(pte) &= ~(_PAGE_MODIFIED|_PAGE_SILENT_WRITE);
  287.     return pte;
  288. }
  289.  
  290. static inline pte_t pte_mkold(pte_t pte)
  291. {
  292.     pte_val(pte) &= ~(_PAGE_ACCESSED|_PAGE_SILENT_READ);
  293.     return pte;
  294. }
  295.  
  296. static inline pte_t pte_mkwrite(pte_t pte)
  297. {
  298.     pte_val(pte) |= _PAGE_WRITE;
  299.     if (pte_val(pte) & _PAGE_MODIFIED)
  300.         pte_val(pte) |= _PAGE_SILENT_WRITE;
  301.     return pte;
  302. }
  303.  
  304. static inline pte_t pte_mkread(pte_t pte)
  305. {
  306.     pte_val(pte) |= _PAGE_READ;
  307.     if (pte_val(pte) & _PAGE_ACCESSED)
  308.         pte_val(pte) |= _PAGE_SILENT_READ;
  309.     return pte;
  310. }
  311.  
  312. static inline pte_t pte_mkdirty(pte_t pte)
  313. {
  314.     pte_val(pte) |= _PAGE_MODIFIED;
  315.     if (pte_val(pte) & _PAGE_WRITE)
  316.         pte_val(pte) |= _PAGE_SILENT_WRITE;
  317.     return pte;
  318. }
  319.  
  320. static inline pte_t pte_mkyoung(pte_t pte)
  321. {
  322.     pte_val(pte) |= _PAGE_ACCESSED;
  323.     if (pte_val(pte) & _PAGE_READ)
  324.         pte_val(pte) |= _PAGE_SILENT_READ;
  325.     return pte;
  326. }
  327. #endif
  328.  
  329. /*
  330.  * Macro to make mark a page protection value as "uncacheable".  Note
  331.  * that "protection" is really a misnomer here as the protection value
  332.  * contains the memory attribute bits, dirty bits, and various other
  333.  * bits as well.
  334.  */
  335. #define pgprot_noncached pgprot_noncached
  336.  
  337. static inline pgprot_t pgprot_noncached(pgprot_t _prot)
  338. {
  339.     unsigned long prot = pgprot_val(_prot);
  340.  
  341.     prot = (prot & ~_CACHE_MASK) | _CACHE_UNCACHED;
  342.  
  343.     return __pgprot(prot);
  344. }
  345.  
  346. /*
  347.  * Conversion functions: convert a page and protection to a page entry,
  348.  * and a page entry and page directory to the page they refer to.
  349.  */
  350. #define mk_pte(page, pgprot)    pfn_pte(page_to_pfn(page), (pgprot))
  351.  
  352. #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32_R1)
  353. static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
  354. {
  355.     pte.pte_low  &= _PAGE_CHG_MASK;
  356.     pte.pte_high &= ~0x3f;
  357.     pte.pte_low  |= pgprot_val(newprot);
  358.     pte.pte_high |= pgprot_val(newprot) & 0x3f;
  359.     return pte;
  360. }
  361. #else
  362. static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
  363. {
  364.     return __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot));
  365. }
  366. #endif
  367.  
  368.  
  369. extern void __update_tlb(struct vm_area_struct *vma, unsigned long address,
  370.     pte_t pte);
  371. extern void __update_cache(struct vm_area_struct *vma, unsigned long address,
  372.     pte_t pte);
  373.  
  374. static inline void update_mmu_cache(struct vm_area_struct *vma,
  375.     unsigned long address, pte_t pte)
  376. {
  377.     __update_tlb(vma, address, pte);
  378.     __update_cache(vma, address, pte);
  379. }
  380.  
  381. #ifndef CONFIG_NEED_MULTIPLE_NODES
  382. #define kern_addr_valid(addr)    (1)
  383. #endif
  384.  
  385. #ifdef CONFIG_64BIT_PHYS_ADDR
  386. extern int remap_pfn_range(struct vm_area_struct *vma, unsigned long from, unsigned long pfn, unsigned long size, pgprot_t prot);
  387.  
  388. static inline int io_remap_pfn_range(struct vm_area_struct *vma,
  389.         unsigned long vaddr,
  390.         unsigned long pfn,
  391.         unsigned long size,
  392.         pgprot_t prot)
  393. {
  394.     phys_t phys_addr_high = fixup_bigphys_addr(pfn << PAGE_SHIFT, size);
  395.     return remap_pfn_range(vma, vaddr, phys_addr_high >> PAGE_SHIFT, size, prot);
  396. }
  397. #else
  398. #define io_remap_pfn_range(vma, vaddr, pfn, size, prot)        \
  399.         remap_pfn_range(vma, vaddr, pfn, size, prot)
  400. #endif
  401.  
  402. #define MK_IOSPACE_PFN(space, pfn)    (pfn)
  403. #define GET_IOSPACE(pfn)        0
  404. #define GET_PFN(pfn)            (pfn)
  405.  
  406. #include <asm-generic/pgtable.h>
  407.  
  408. /*
  409.  * We provide our own get_unmapped area to cope with the virtual aliasing
  410.  * constraints placed on us by the cache architecture.
  411.  */
  412. #define HAVE_ARCH_UNMAPPED_AREA
  413.  
  414. /*
  415.  * No page table caches to initialise
  416.  */
  417. #define pgtable_cache_init()    do { } while (0)
  418.  
  419. #endif /* _ASM_PGTABLE_H */
  420.