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-sparc64 / pgtable.h < prev    next >
Encoding:
C/C++ Source or Header  |  2006-08-11  |  24.1 KB  |  796 lines

  1. /* $Id: pgtable.h,v 1.156 2002/02/09 19:49:31 davem Exp $
  2.  * pgtable.h: SpitFire page table operations.
  3.  *
  4.  * Copyright 1996,1997 David S. Miller (davem@caip.rutgers.edu)
  5.  * Copyright 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
  6.  */
  7.  
  8. #ifndef _SPARC64_PGTABLE_H
  9. #define _SPARC64_PGTABLE_H
  10.  
  11. /* This file contains the functions and defines necessary to modify and use
  12.  * the SpitFire page tables.
  13.  */
  14.  
  15. #include <asm-generic/pgtable-nopud.h>
  16.  
  17. #include <linux/compiler.h>
  18. #include <asm/types.h>
  19. #include <asm/spitfire.h>
  20. #include <asm/asi.h>
  21. #include <asm/system.h>
  22. #include <asm/page.h>
  23. #include <asm/processor.h>
  24. #include <asm/const.h>
  25.  
  26. /* The kernel image occupies 0x4000000 to 0x1000000 (4MB --> 32MB).
  27.  * The page copy blockops can use 0x2000000 to 0x4000000.
  28.  * The TSB is mapped in the 0x4000000 to 0x6000000 range.
  29.  * The PROM resides in an area spanning 0xf0000000 to 0x100000000.
  30.  * The vmalloc area spans 0x100000000 to 0x200000000.
  31.  * Since modules need to be in the lowest 32-bits of the address space,
  32.  * we place them right before the OBP area from 0x10000000 to 0xf0000000.
  33.  * There is a single static kernel PMD which maps from 0x0 to address
  34.  * 0x400000000.
  35.  */
  36. #define    TLBTEMP_BASE        _AC(0x0000000002000000,UL)
  37. #define    TSBMAP_BASE        _AC(0x0000000004000000,UL)
  38. #define MODULES_VADDR        _AC(0x0000000010000000,UL)
  39. #define MODULES_LEN        _AC(0x00000000e0000000,UL)
  40. #define MODULES_END        _AC(0x00000000f0000000,UL)
  41. #define LOW_OBP_ADDRESS        _AC(0x00000000f0000000,UL)
  42. #define HI_OBP_ADDRESS        _AC(0x0000000100000000,UL)
  43. #define VMALLOC_START        _AC(0x0000000100000000,UL)
  44. #define VMALLOC_END        _AC(0x0000000200000000,UL)
  45.  
  46. /* XXX All of this needs to be rethought so we can take advantage
  47.  * XXX cheetah's full 64-bit virtual address space, ie. no more hole
  48.  * XXX in the middle like on spitfire. -DaveM
  49.  */
  50. /*
  51.  * Given a virtual address, the lowest PAGE_SHIFT bits determine offset
  52.  * into the page; the next higher PAGE_SHIFT-3 bits determine the pte#
  53.  * in the proper pagetable (the -3 is from the 8 byte ptes, and each page
  54.  * table is a single page long). The next higher PMD_BITS determine pmd# 
  55.  * in the proper pmdtable (where we must have PMD_BITS <= (PAGE_SHIFT-2) 
  56.  * since the pmd entries are 4 bytes, and each pmd page is a single page 
  57.  * long). Finally, the higher few bits determine pgde#.
  58.  */
  59.  
  60. /* PMD_SHIFT determines the size of the area a second-level page
  61.  * table can map
  62.  */
  63. #define PMD_SHIFT    (PAGE_SHIFT + (PAGE_SHIFT-3))
  64. #define PMD_SIZE    (_AC(1,UL) << PMD_SHIFT)
  65. #define PMD_MASK    (~(PMD_SIZE-1))
  66. #define PMD_BITS    (PAGE_SHIFT - 2)
  67.  
  68. /* PGDIR_SHIFT determines what a third-level page table entry can map */
  69. #define PGDIR_SHIFT    (PAGE_SHIFT + (PAGE_SHIFT-3) + PMD_BITS)
  70. #define PGDIR_SIZE    (_AC(1,UL) << PGDIR_SHIFT)
  71. #define PGDIR_MASK    (~(PGDIR_SIZE-1))
  72. #define PGDIR_BITS    (PAGE_SHIFT - 2)
  73.  
  74. #ifndef __ASSEMBLY__
  75.  
  76. #include <linux/sched.h>
  77.  
  78. /* Entries per page directory level. */
  79. #define PTRS_PER_PTE    (1UL << (PAGE_SHIFT-3))
  80. #define PTRS_PER_PMD    (1UL << PMD_BITS)
  81. #define PTRS_PER_PGD    (1UL << PGDIR_BITS)
  82.  
  83. /* Kernel has a separate 44bit address space. */
  84. #define FIRST_USER_ADDRESS    0
  85.  
  86. #define pte_ERROR(e)    __builtin_trap()
  87. #define pmd_ERROR(e)    __builtin_trap()
  88. #define pgd_ERROR(e)    __builtin_trap()
  89.  
  90. #endif /* !(__ASSEMBLY__) */
  91.  
  92. /* PTE bits which are the same in SUN4U and SUN4V format.  */
  93. #define _PAGE_VALID      _AC(0x8000000000000000,UL) /* Valid TTE            */
  94. #define _PAGE_R            _AC(0x8000000000000000,UL) /* Keep ref bit uptodate*/
  95.  
  96. /* SUN4U pte bits... */
  97. #define _PAGE_SZ4MB_4U      _AC(0x6000000000000000,UL) /* 4MB Page             */
  98. #define _PAGE_SZ512K_4U      _AC(0x4000000000000000,UL) /* 512K Page            */
  99. #define _PAGE_SZ64K_4U      _AC(0x2000000000000000,UL) /* 64K Page             */
  100. #define _PAGE_SZ8K_4U      _AC(0x0000000000000000,UL) /* 8K Page              */
  101. #define _PAGE_NFO_4U      _AC(0x1000000000000000,UL) /* No Fault Only        */
  102. #define _PAGE_IE_4U      _AC(0x0800000000000000,UL) /* Invert Endianness    */
  103. #define _PAGE_SOFT2_4U      _AC(0x07FC000000000000,UL) /* Software bits, set 2 */
  104. #define _PAGE_RES1_4U      _AC(0x0002000000000000,UL) /* Reserved             */
  105. #define _PAGE_SZ32MB_4U      _AC(0x0001000000000000,UL) /* (Panther) 32MB page  */
  106. #define _PAGE_SZ256MB_4U  _AC(0x2001000000000000,UL) /* (Panther) 256MB page */
  107. #define _PAGE_SZALL_4U      _AC(0x6001000000000000,UL) /* All pgsz bits        */
  108. #define _PAGE_SN_4U      _AC(0x0000800000000000,UL) /* (Cheetah) Snoop      */
  109. #define _PAGE_RES2_4U      _AC(0x0000780000000000,UL) /* Reserved             */
  110. #define _PAGE_PADDR_4U      _AC(0x000007FFFFFFE000,UL) /* (Cheetah) pa[42:13]  */
  111. #define _PAGE_SOFT_4U      _AC(0x0000000000001F80,UL) /* Software bits:       */
  112. #define _PAGE_EXEC_4U      _AC(0x0000000000001000,UL) /* Executable SW bit    */
  113. #define _PAGE_MODIFIED_4U _AC(0x0000000000000800,UL) /* Modified (dirty)     */
  114. #define _PAGE_FILE_4U      _AC(0x0000000000000800,UL) /* Pagecache page       */
  115. #define _PAGE_ACCESSED_4U _AC(0x0000000000000400,UL) /* Accessed (ref'd)     */
  116. #define _PAGE_READ_4U      _AC(0x0000000000000200,UL) /* Readable SW Bit      */
  117. #define _PAGE_WRITE_4U      _AC(0x0000000000000100,UL) /* Writable SW Bit      */
  118. #define _PAGE_PRESENT_4U  _AC(0x0000000000000080,UL) /* Present              */
  119. #define _PAGE_L_4U      _AC(0x0000000000000040,UL) /* Locked TTE           */
  120. #define _PAGE_CP_4U      _AC(0x0000000000000020,UL) /* Cacheable in P-Cache */
  121. #define _PAGE_CV_4U      _AC(0x0000000000000010,UL) /* Cacheable in V-Cache */
  122. #define _PAGE_E_4U      _AC(0x0000000000000008,UL) /* side-Effect          */
  123. #define _PAGE_P_4U      _AC(0x0000000000000004,UL) /* Privileged Page      */
  124. #define _PAGE_W_4U      _AC(0x0000000000000002,UL) /* Writable             */
  125.  
  126. /* SUN4V pte bits... */
  127. #define _PAGE_NFO_4V      _AC(0x4000000000000000,UL) /* No Fault Only        */
  128. #define _PAGE_SOFT2_4V      _AC(0x3F00000000000000,UL) /* Software bits, set 2 */
  129. #define _PAGE_MODIFIED_4V _AC(0x2000000000000000,UL) /* Modified (dirty)     */
  130. #define _PAGE_ACCESSED_4V _AC(0x1000000000000000,UL) /* Accessed (ref'd)     */
  131. #define _PAGE_READ_4V      _AC(0x0800000000000000,UL) /* Readable SW Bit      */
  132. #define _PAGE_WRITE_4V      _AC(0x0400000000000000,UL) /* Writable SW Bit      */
  133. #define _PAGE_PADDR_4V      _AC(0x00FFFFFFFFFFE000,UL) /* paddr[55:13]         */
  134. #define _PAGE_IE_4V      _AC(0x0000000000001000,UL) /* Invert Endianness    */
  135. #define _PAGE_E_4V      _AC(0x0000000000000800,UL) /* side-Effect          */
  136. #define _PAGE_CP_4V      _AC(0x0000000000000400,UL) /* Cacheable in P-Cache */
  137. #define _PAGE_CV_4V      _AC(0x0000000000000200,UL) /* Cacheable in V-Cache */
  138. #define _PAGE_P_4V      _AC(0x0000000000000100,UL) /* Privileged Page      */
  139. #define _PAGE_EXEC_4V      _AC(0x0000000000000080,UL) /* Executable Page      */
  140. #define _PAGE_W_4V      _AC(0x0000000000000040,UL) /* Writable             */
  141. #define _PAGE_SOFT_4V      _AC(0x0000000000000030,UL) /* Software bits        */
  142. #define _PAGE_FILE_4V      _AC(0x0000000000000020,UL) /* Pagecache page       */
  143. #define _PAGE_PRESENT_4V  _AC(0x0000000000000010,UL) /* Present              */
  144. #define _PAGE_RESV_4V      _AC(0x0000000000000008,UL) /* Reserved             */
  145. #define _PAGE_SZ16GB_4V      _AC(0x0000000000000007,UL) /* 16GB Page            */
  146. #define _PAGE_SZ2GB_4V      _AC(0x0000000000000006,UL) /* 2GB Page             */
  147. #define _PAGE_SZ256MB_4V  _AC(0x0000000000000005,UL) /* 256MB Page           */
  148. #define _PAGE_SZ32MB_4V      _AC(0x0000000000000004,UL) /* 32MB Page            */
  149. #define _PAGE_SZ4MB_4V      _AC(0x0000000000000003,UL) /* 4MB Page             */
  150. #define _PAGE_SZ512K_4V      _AC(0x0000000000000002,UL) /* 512K Page            */
  151. #define _PAGE_SZ64K_4V      _AC(0x0000000000000001,UL) /* 64K Page             */
  152. #define _PAGE_SZ8K_4V      _AC(0x0000000000000000,UL) /* 8K Page              */
  153. #define _PAGE_SZALL_4V      _AC(0x0000000000000007,UL) /* All pgsz bits        */
  154.  
  155. #if PAGE_SHIFT == 13
  156. #define _PAGE_SZBITS_4U    _PAGE_SZ8K_4U
  157. #define _PAGE_SZBITS_4V    _PAGE_SZ8K_4V
  158. #elif PAGE_SHIFT == 16
  159. #define _PAGE_SZBITS_4U    _PAGE_SZ64K_4U
  160. #define _PAGE_SZBITS_4V    _PAGE_SZ64K_4V
  161. #elif PAGE_SHIFT == 19
  162. #define _PAGE_SZBITS_4U    _PAGE_SZ512K_4U
  163. #define _PAGE_SZBITS_4V    _PAGE_SZ512K_4V
  164. #elif PAGE_SHIFT == 22
  165. #define _PAGE_SZBITS_4U    _PAGE_SZ4MB_4U
  166. #define _PAGE_SZBITS_4V    _PAGE_SZ4MB_4V
  167. #else
  168. #error Wrong PAGE_SHIFT specified
  169. #endif
  170.  
  171. #if defined(CONFIG_HUGETLB_PAGE_SIZE_4MB)
  172. #define _PAGE_SZHUGE_4U    _PAGE_SZ4MB_4U
  173. #define _PAGE_SZHUGE_4V    _PAGE_SZ4MB_4V
  174. #elif defined(CONFIG_HUGETLB_PAGE_SIZE_512K)
  175. #define _PAGE_SZHUGE_4U    _PAGE_SZ512K_4U
  176. #define _PAGE_SZHUGE_4V    _PAGE_SZ512K_4V
  177. #elif defined(CONFIG_HUGETLB_PAGE_SIZE_64K)
  178. #define _PAGE_SZHUGE_4U    _PAGE_SZ64K_4U
  179. #define _PAGE_SZHUGE_4V    _PAGE_SZ64K_4V
  180. #endif
  181.  
  182. /* These are actually filled in at boot time by sun4{u,v}_pgprot_init() */
  183. #define __P000    __pgprot(0)
  184. #define __P001    __pgprot(0)
  185. #define __P010    __pgprot(0)
  186. #define __P011    __pgprot(0)
  187. #define __P100    __pgprot(0)
  188. #define __P101    __pgprot(0)
  189. #define __P110    __pgprot(0)
  190. #define __P111    __pgprot(0)
  191.  
  192. #define __S000    __pgprot(0)
  193. #define __S001    __pgprot(0)
  194. #define __S010    __pgprot(0)
  195. #define __S011    __pgprot(0)
  196. #define __S100    __pgprot(0)
  197. #define __S101    __pgprot(0)
  198. #define __S110    __pgprot(0)
  199. #define __S111    __pgprot(0)
  200.  
  201. #ifndef __ASSEMBLY__
  202.  
  203. extern pte_t mk_pte_io(unsigned long, pgprot_t, int, unsigned long);
  204.  
  205. extern unsigned long pte_sz_bits(unsigned long size);
  206.  
  207. extern pgprot_t PAGE_KERNEL;
  208. extern pgprot_t PAGE_KERNEL_LOCKED;
  209. extern pgprot_t PAGE_COPY;
  210. extern pgprot_t PAGE_SHARED;
  211.  
  212. /* XXX This uglyness is for the atyfb driver's sparc mmap() support. XXX */
  213. extern unsigned long _PAGE_IE;
  214. extern unsigned long _PAGE_E;
  215. extern unsigned long _PAGE_CACHE;
  216.  
  217. extern unsigned long pg_iobits;
  218. extern unsigned long _PAGE_ALL_SZ_BITS;
  219. extern unsigned long _PAGE_SZBITS;
  220.  
  221. extern struct page *mem_map_zero;
  222. #define ZERO_PAGE(vaddr)    (mem_map_zero)
  223.  
  224. /* PFNs are real physical page numbers.  However, mem_map only begins to record
  225.  * per-page information starting at pfn_base.  This is to handle systems where
  226.  * the first physical page in the machine is at some huge physical address,
  227.  * such as 4GB.   This is common on a partitioned E10000, for example.
  228.  */
  229. static inline pte_t pfn_pte(unsigned long pfn, pgprot_t prot)
  230. {
  231.     unsigned long paddr = pfn << PAGE_SHIFT;
  232.     unsigned long sz_bits;
  233.  
  234.     sz_bits = 0UL;
  235.     if (_PAGE_SZBITS_4U != 0UL || _PAGE_SZBITS_4V != 0UL) {
  236.         __asm__ __volatile__(
  237.         "\n661:    sethi        %uhi(%1), %0\n"
  238.         "    sllx        %0, 32, %0\n"
  239.         "    .section    .sun4v_2insn_patch, \"ax\"\n"
  240.         "    .word        661b\n"
  241.         "    mov        %2, %0\n"
  242.         "    nop\n"
  243.         "    .previous\n"
  244.         : "=r" (sz_bits)
  245.         : "i" (_PAGE_SZBITS_4U), "i" (_PAGE_SZBITS_4V));
  246.     }
  247.     return __pte(paddr | sz_bits | pgprot_val(prot));
  248. }
  249. #define mk_pte(page, pgprot)    pfn_pte(page_to_pfn(page), (pgprot))
  250.  
  251. /* This one can be done with two shifts.  */
  252. static inline unsigned long pte_pfn(pte_t pte)
  253. {
  254.     unsigned long ret;
  255.  
  256.     __asm__ __volatile__(
  257.     "\n661:    sllx        %1, %2, %0\n"
  258.     "    srlx        %0, %3, %0\n"
  259.     "    .section    .sun4v_2insn_patch, \"ax\"\n"
  260.     "    .word        661b\n"
  261.     "    sllx        %1, %4, %0\n"
  262.     "    srlx        %0, %5, %0\n"
  263.     "    .previous\n"
  264.     : "=r" (ret)
  265.     : "r" (pte_val(pte)),
  266.       "i" (21), "i" (21 + PAGE_SHIFT),
  267.       "i" (8), "i" (8 + PAGE_SHIFT));
  268.  
  269.     return ret;
  270. }
  271. #define pte_page(x) pfn_to_page(pte_pfn(x))
  272.  
  273. static inline pte_t pte_modify(pte_t pte, pgprot_t prot)
  274. {
  275.     unsigned long mask, tmp;
  276.  
  277.     /* SUN4U: 0x600307ffffffecb8 (negated == 0x9ffcf80000001347)
  278.      * SUN4V: 0x30ffffffffffee17 (negated == 0xcf000000000011e8)
  279.      *
  280.      * Even if we use negation tricks the result is still a 6
  281.      * instruction sequence, so don't try to play fancy and just
  282.      * do the most straightforward implementation.
  283.      *
  284.      * Note: We encode this into 3 sun4v 2-insn patch sequences.
  285.      */
  286.  
  287.     __asm__ __volatile__(
  288.     "\n661:    sethi        %%uhi(%2), %1\n"
  289.     "    sethi        %%hi(%2), %0\n"
  290.     "\n662:    or        %1, %%ulo(%2), %1\n"
  291.     "    or        %0, %%lo(%2), %0\n"
  292.     "\n663:    sllx        %1, 32, %1\n"
  293.     "    or        %0, %1, %0\n"
  294.     "    .section    .sun4v_2insn_patch, \"ax\"\n"
  295.     "    .word        661b\n"
  296.     "    sethi        %%uhi(%3), %1\n"
  297.     "    sethi        %%hi(%3), %0\n"
  298.     "    .word        662b\n"
  299.     "    or        %1, %%ulo(%3), %1\n"
  300.     "    or        %0, %%lo(%3), %0\n"
  301.     "    .word        663b\n"
  302.     "    sllx        %1, 32, %1\n"
  303.     "    or        %0, %1, %0\n"
  304.     "    .previous\n"
  305.     : "=r" (mask), "=r" (tmp)
  306.     : "i" (_PAGE_PADDR_4U | _PAGE_MODIFIED_4U | _PAGE_ACCESSED_4U |
  307.            _PAGE_CP_4U | _PAGE_CV_4U | _PAGE_E_4U | _PAGE_PRESENT_4U |
  308.            _PAGE_SZBITS_4U),
  309.       "i" (_PAGE_PADDR_4V | _PAGE_MODIFIED_4V | _PAGE_ACCESSED_4V |
  310.            _PAGE_CP_4V | _PAGE_CV_4V | _PAGE_E_4V | _PAGE_PRESENT_4V |
  311.            _PAGE_SZBITS_4V));
  312.  
  313.     return __pte((pte_val(pte) & mask) | (pgprot_val(prot) & ~mask));
  314. }
  315.  
  316. static inline pte_t pgoff_to_pte(unsigned long off)
  317. {
  318.     off <<= PAGE_SHIFT;
  319.  
  320.     __asm__ __volatile__(
  321.     "\n661:    or        %0, %2, %0\n"
  322.     "    .section    .sun4v_1insn_patch, \"ax\"\n"
  323.     "    .word        661b\n"
  324.     "    or        %0, %3, %0\n"
  325.     "    .previous\n"
  326.     : "=r" (off)
  327.     : "0" (off), "i" (_PAGE_FILE_4U), "i" (_PAGE_FILE_4V));
  328.  
  329.     return __pte(off);
  330. }
  331.  
  332. static inline pgprot_t pgprot_noncached(pgprot_t prot)
  333. {
  334.     unsigned long val = pgprot_val(prot);
  335.  
  336.     __asm__ __volatile__(
  337.     "\n661:    andn        %0, %2, %0\n"
  338.     "    or        %0, %3, %0\n"
  339.     "    .section    .sun4v_2insn_patch, \"ax\"\n"
  340.     "    .word        661b\n"
  341.     "    andn        %0, %4, %0\n"
  342.     "    or        %0, %5, %0\n"
  343.     "    .previous\n"
  344.     : "=r" (val)
  345.     : "0" (val), "i" (_PAGE_CP_4U | _PAGE_CV_4U), "i" (_PAGE_E_4U),
  346.                  "i" (_PAGE_CP_4V | _PAGE_CV_4V), "i" (_PAGE_E_4V));
  347.  
  348.     return __pgprot(val);
  349. }
  350. /* Various pieces of code check for platform support by ifdef testing
  351.  * on "pgprot_noncached".  That's broken and should be fixed, but for
  352.  * now...
  353.  */
  354. #define pgprot_noncached pgprot_noncached
  355.  
  356. #ifdef CONFIG_HUGETLB_PAGE
  357. static inline pte_t pte_mkhuge(pte_t pte)
  358. {
  359.     unsigned long mask;
  360.  
  361.     __asm__ __volatile__(
  362.     "\n661:    sethi        %%uhi(%1), %0\n"
  363.     "    sllx        %0, 32, %0\n"
  364.     "    .section    .sun4v_2insn_patch, \"ax\"\n"
  365.     "    .word        661b\n"
  366.     "    mov        %2, %0\n"
  367.     "    nop\n"
  368.     "    .previous\n"
  369.     : "=r" (mask)
  370.     : "i" (_PAGE_SZHUGE_4U), "i" (_PAGE_SZHUGE_4V));
  371.  
  372.     return __pte(pte_val(pte) | mask);
  373. }
  374. #endif
  375.  
  376. static inline pte_t pte_mkdirty(pte_t pte)
  377. {
  378.     unsigned long val = pte_val(pte), tmp;
  379.  
  380.     __asm__ __volatile__(
  381.     "\n661:    or        %0, %3, %0\n"
  382.     "    nop\n"
  383.     "\n662:    nop\n"
  384.     "    nop\n"
  385.     "    .section    .sun4v_2insn_patch, \"ax\"\n"
  386.     "    .word        661b\n"
  387.     "    sethi        %%uhi(%4), %1\n"
  388.     "    sllx        %1, 32, %1\n"
  389.     "    .word        662b\n"
  390.     "    or        %1, %%lo(%4), %1\n"
  391.     "    or        %0, %1, %0\n"
  392.     "    .previous\n"
  393.     : "=r" (val), "=r" (tmp)
  394.     : "0" (val), "i" (_PAGE_MODIFIED_4U | _PAGE_W_4U),
  395.       "i" (_PAGE_MODIFIED_4V | _PAGE_W_4V));
  396.  
  397.     return __pte(val);
  398. }
  399.  
  400. static inline pte_t pte_mkclean(pte_t pte)
  401. {
  402.     unsigned long val = pte_val(pte), tmp;
  403.  
  404.     __asm__ __volatile__(
  405.     "\n661:    andn        %0, %3, %0\n"
  406.     "    nop\n"
  407.     "\n662:    nop\n"
  408.     "    nop\n"
  409.     "    .section    .sun4v_2insn_patch, \"ax\"\n"
  410.     "    .word        661b\n"
  411.     "    sethi        %%uhi(%4), %1\n"
  412.     "    sllx        %1, 32, %1\n"
  413.     "    .word        662b\n"
  414.     "    or        %1, %%lo(%4), %1\n"
  415.     "    andn        %0, %1, %0\n"
  416.     "    .previous\n"
  417.     : "=r" (val), "=r" (tmp)
  418.     : "0" (val), "i" (_PAGE_MODIFIED_4U | _PAGE_W_4U),
  419.       "i" (_PAGE_MODIFIED_4V | _PAGE_W_4V));
  420.  
  421.     return __pte(val);
  422. }
  423.  
  424. static inline pte_t pte_mkwrite(pte_t pte)
  425. {
  426.     unsigned long val = pte_val(pte), mask;
  427.  
  428.     __asm__ __volatile__(
  429.     "\n661:    mov        %1, %0\n"
  430.     "    nop\n"
  431.     "    .section    .sun4v_2insn_patch, \"ax\"\n"
  432.     "    .word        661b\n"
  433.     "    sethi        %%uhi(%2), %0\n"
  434.     "    sllx        %0, 32, %0\n"
  435.     "    .previous\n"
  436.     : "=r" (mask)
  437.     : "i" (_PAGE_WRITE_4U), "i" (_PAGE_WRITE_4V));
  438.  
  439.     return __pte(val | mask);
  440. }
  441.  
  442. static inline pte_t pte_wrprotect(pte_t pte)
  443. {
  444.     unsigned long val = pte_val(pte), tmp;
  445.  
  446.     __asm__ __volatile__(
  447.     "\n661:    andn        %0, %3, %0\n"
  448.     "    nop\n"
  449.     "\n662:    nop\n"
  450.     "    nop\n"
  451.     "    .section    .sun4v_2insn_patch, \"ax\"\n"
  452.     "    .word        661b\n"
  453.     "    sethi        %%uhi(%4), %1\n"
  454.     "    sllx        %1, 32, %1\n"
  455.     "    .word        662b\n"
  456.     "    or        %1, %%lo(%4), %1\n"
  457.     "    andn        %0, %1, %0\n"
  458.     "    .previous\n"
  459.     : "=r" (val), "=r" (tmp)
  460.     : "0" (val), "i" (_PAGE_WRITE_4U | _PAGE_W_4U),
  461.       "i" (_PAGE_WRITE_4V | _PAGE_W_4V));
  462.  
  463.     return __pte(val);
  464. }
  465.  
  466. static inline pte_t pte_mkold(pte_t pte)
  467. {
  468.     unsigned long mask;
  469.  
  470.     __asm__ __volatile__(
  471.     "\n661:    mov        %1, %0\n"
  472.     "    nop\n"
  473.     "    .section    .sun4v_2insn_patch, \"ax\"\n"
  474.     "    .word        661b\n"
  475.     "    sethi        %%uhi(%2), %0\n"
  476.     "    sllx        %0, 32, %0\n"
  477.     "    .previous\n"
  478.     : "=r" (mask)
  479.     : "i" (_PAGE_ACCESSED_4U), "i" (_PAGE_ACCESSED_4V));
  480.  
  481.     mask |= _PAGE_R;
  482.  
  483.     return __pte(pte_val(pte) & ~mask);
  484. }
  485.  
  486. static inline pte_t pte_mkyoung(pte_t pte)
  487. {
  488.     unsigned long mask;
  489.  
  490.     __asm__ __volatile__(
  491.     "\n661:    mov        %1, %0\n"
  492.     "    nop\n"
  493.     "    .section    .sun4v_2insn_patch, \"ax\"\n"
  494.     "    .word        661b\n"
  495.     "    sethi        %%uhi(%2), %0\n"
  496.     "    sllx        %0, 32, %0\n"
  497.     "    .previous\n"
  498.     : "=r" (mask)
  499.     : "i" (_PAGE_ACCESSED_4U), "i" (_PAGE_ACCESSED_4V));
  500.  
  501.     mask |= _PAGE_R;
  502.  
  503.     return __pte(pte_val(pte) | mask);
  504. }
  505.  
  506. static inline unsigned long pte_young(pte_t pte)
  507. {
  508.     unsigned long mask;
  509.  
  510.     __asm__ __volatile__(
  511.     "\n661:    mov        %1, %0\n"
  512.     "    nop\n"
  513.     "    .section    .sun4v_2insn_patch, \"ax\"\n"
  514.     "    .word        661b\n"
  515.     "    sethi        %%uhi(%2), %0\n"
  516.     "    sllx        %0, 32, %0\n"
  517.     "    .previous\n"
  518.     : "=r" (mask)
  519.     : "i" (_PAGE_ACCESSED_4U), "i" (_PAGE_ACCESSED_4V));
  520.  
  521.     return (pte_val(pte) & mask);
  522. }
  523.  
  524. static inline unsigned long pte_dirty(pte_t pte)
  525. {
  526.     unsigned long mask;
  527.  
  528.     __asm__ __volatile__(
  529.     "\n661:    mov        %1, %0\n"
  530.     "    nop\n"
  531.     "    .section    .sun4v_2insn_patch, \"ax\"\n"
  532.     "    .word        661b\n"
  533.     "    sethi        %%uhi(%2), %0\n"
  534.     "    sllx        %0, 32, %0\n"
  535.     "    .previous\n"
  536.     : "=r" (mask)
  537.     : "i" (_PAGE_MODIFIED_4U), "i" (_PAGE_MODIFIED_4V));
  538.  
  539.     return (pte_val(pte) & mask);
  540. }
  541.  
  542. static inline unsigned long pte_write(pte_t pte)
  543. {
  544.     unsigned long mask;
  545.  
  546.     __asm__ __volatile__(
  547.     "\n661:    mov        %1, %0\n"
  548.     "    nop\n"
  549.     "    .section    .sun4v_2insn_patch, \"ax\"\n"
  550.     "    .word        661b\n"
  551.     "    sethi        %%uhi(%2), %0\n"
  552.     "    sllx        %0, 32, %0\n"
  553.     "    .previous\n"
  554.     : "=r" (mask)
  555.     : "i" (_PAGE_WRITE_4U), "i" (_PAGE_WRITE_4V));
  556.  
  557.     return (pte_val(pte) & mask);
  558. }
  559.  
  560. static inline unsigned long pte_exec(pte_t pte)
  561. {
  562.     unsigned long mask;
  563.  
  564.     __asm__ __volatile__(
  565.     "\n661:    sethi        %%hi(%1), %0\n"
  566.     "    .section    .sun4v_1insn_patch, \"ax\"\n"
  567.     "    .word        661b\n"
  568.     "    mov        %2, %0\n"
  569.     "    .previous\n"
  570.     : "=r" (mask)
  571.     : "i" (_PAGE_EXEC_4U), "i" (_PAGE_EXEC_4V));
  572.  
  573.     return (pte_val(pte) & mask);
  574. }
  575.  
  576. static inline unsigned long pte_read(pte_t pte)
  577. {
  578.     unsigned long mask;
  579.  
  580.     __asm__ __volatile__(
  581.     "\n661:    mov        %1, %0\n"
  582.     "    nop\n"
  583.     "    .section    .sun4v_2insn_patch, \"ax\"\n"
  584.     "    .word        661b\n"
  585.     "    sethi        %%uhi(%2), %0\n"
  586.     "    sllx        %0, 32, %0\n"
  587.     "    .previous\n"
  588.     : "=r" (mask)
  589.     : "i" (_PAGE_READ_4U), "i" (_PAGE_READ_4V));
  590.  
  591.     return (pte_val(pte) & mask);
  592. }
  593.  
  594. static inline unsigned long pte_file(pte_t pte)
  595. {
  596.     unsigned long val = pte_val(pte);
  597.  
  598.     __asm__ __volatile__(
  599.     "\n661:    and        %0, %2, %0\n"
  600.     "    .section    .sun4v_1insn_patch, \"ax\"\n"
  601.     "    .word        661b\n"
  602.     "    and        %0, %3, %0\n"
  603.     "    .previous\n"
  604.     : "=r" (val)
  605.     : "0" (val), "i" (_PAGE_FILE_4U), "i" (_PAGE_FILE_4V));
  606.  
  607.     return val;
  608. }
  609.  
  610. static inline unsigned long pte_present(pte_t pte)
  611. {
  612.     unsigned long val = pte_val(pte);
  613.  
  614.     __asm__ __volatile__(
  615.     "\n661:    and        %0, %2, %0\n"
  616.     "    .section    .sun4v_1insn_patch, \"ax\"\n"
  617.     "    .word        661b\n"
  618.     "    and        %0, %3, %0\n"
  619.     "    .previous\n"
  620.     : "=r" (val)
  621.     : "0" (val), "i" (_PAGE_PRESENT_4U), "i" (_PAGE_PRESENT_4V));
  622.  
  623.     return val;
  624. }
  625.  
  626. #define pmd_set(pmdp, ptep)    \
  627.     (pmd_val(*(pmdp)) = (__pa((unsigned long) (ptep)) >> 11UL))
  628. #define pud_set(pudp, pmdp)    \
  629.     (pud_val(*(pudp)) = (__pa((unsigned long) (pmdp)) >> 11UL))
  630. #define __pmd_page(pmd)        \
  631.     ((unsigned long) __va((((unsigned long)pmd_val(pmd))<<11UL)))
  632. #define pmd_page(pmd)             virt_to_page((void *)__pmd_page(pmd))
  633. #define pud_page(pud)        \
  634.     ((unsigned long) __va((((unsigned long)pud_val(pud))<<11UL)))
  635. #define pmd_none(pmd)            (!pmd_val(pmd))
  636. #define pmd_bad(pmd)            (0)
  637. #define pmd_present(pmd)        (pmd_val(pmd) != 0U)
  638. #define pmd_clear(pmdp)            (pmd_val(*(pmdp)) = 0U)
  639. #define pud_none(pud)            (!pud_val(pud))
  640. #define pud_bad(pud)            (0)
  641. #define pud_present(pud)        (pud_val(pud) != 0U)
  642. #define pud_clear(pudp)            (pud_val(*(pudp)) = 0U)
  643.  
  644. /* Same in both SUN4V and SUN4U.  */
  645. #define pte_none(pte)             (!pte_val(pte))
  646.  
  647. /* to find an entry in a page-table-directory. */
  648. #define pgd_index(address)    (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1))
  649. #define pgd_offset(mm, address)    ((mm)->pgd + pgd_index(address))
  650.  
  651. /* to find an entry in a kernel page-table-directory */
  652. #define pgd_offset_k(address) pgd_offset(&init_mm, address)
  653.  
  654. /* Find an entry in the second-level page table.. */
  655. #define pmd_offset(pudp, address)    \
  656.     ((pmd_t *) pud_page(*(pudp)) + \
  657.      (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1)))
  658.  
  659. /* Find an entry in the third-level page table.. */
  660. #define pte_index(dir, address)    \
  661.     ((pte_t *) __pmd_page(*(dir)) + \
  662.      ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)))
  663. #define pte_offset_kernel        pte_index
  664. #define pte_offset_map            pte_index
  665. #define pte_offset_map_nested        pte_index
  666. #define pte_unmap(pte)            do { } while (0)
  667. #define pte_unmap_nested(pte)        do { } while (0)
  668.  
  669. /* Actual page table PTE updates.  */
  670. extern void tlb_batch_add(struct mm_struct *mm, unsigned long vaddr, pte_t *ptep, pte_t orig);
  671.  
  672. static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte)
  673. {
  674.     pte_t orig = *ptep;
  675.  
  676.     *ptep = pte;
  677.  
  678.     /* It is more efficient to let flush_tlb_kernel_range()
  679.      * handle init_mm tlb flushes.
  680.      *
  681.      * SUN4V NOTE: _PAGE_VALID is the same value in both the SUN4U
  682.      *             and SUN4V pte layout, so this inline test is fine.
  683.      */
  684.     if (likely(mm != &init_mm) && (pte_val(orig) & _PAGE_VALID))
  685.         tlb_batch_add(mm, addr, ptep, orig);
  686. }
  687.  
  688. #define pte_clear(mm,addr,ptep)        \
  689.     set_pte_at((mm), (addr), (ptep), __pte(0UL))
  690.  
  691. #ifdef DCACHE_ALIASING_POSSIBLE
  692. #define __HAVE_ARCH_MOVE_PTE
  693. #define move_pte(pte, prot, old_addr, new_addr)                \
  694. ({                                    \
  695.      pte_t newpte = (pte);                        \
  696.     if (tlb_type != hypervisor && pte_present(pte)) {        \
  697.         unsigned long this_pfn = pte_pfn(pte);            \
  698.                                     \
  699.         if (pfn_valid(this_pfn) &&                \
  700.             (((old_addr) ^ (new_addr)) & (1 << 13)))        \
  701.             flush_dcache_page_all(current->mm,        \
  702.                           pfn_to_page(this_pfn));    \
  703.     }                                \
  704.     newpte;                                \
  705. })
  706. #endif
  707.  
  708. extern pgd_t swapper_pg_dir[2048];
  709. extern pmd_t swapper_low_pmd_dir[2048];
  710.  
  711. extern void paging_init(void);
  712. extern unsigned long find_ecache_flush_span(unsigned long size);
  713.  
  714. /* These do nothing with the way I have things setup. */
  715. #define mmu_lockarea(vaddr, len)        (vaddr)
  716. #define mmu_unlockarea(vaddr, len)        do { } while(0)
  717.  
  718. struct vm_area_struct;
  719. extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t);
  720.  
  721. /* Encode and de-code a swap entry */
  722. #define __swp_type(entry)    (((entry).val >> PAGE_SHIFT) & 0xffUL)
  723. #define __swp_offset(entry)    ((entry).val >> (PAGE_SHIFT + 8UL))
  724. #define __swp_entry(type, offset)    \
  725.     ( (swp_entry_t) \
  726.       { \
  727.         (((long)(type) << PAGE_SHIFT) | \
  728.                  ((long)(offset) << (PAGE_SHIFT + 8UL))) \
  729.       } )
  730. #define __pte_to_swp_entry(pte)        ((swp_entry_t) { pte_val(pte) })
  731. #define __swp_entry_to_pte(x)        ((pte_t) { (x).val })
  732.  
  733. /* File offset in PTE support. */
  734. extern unsigned long pte_file(pte_t);
  735. #define pte_to_pgoff(pte)    (pte_val(pte) >> PAGE_SHIFT)
  736. extern pte_t pgoff_to_pte(unsigned long);
  737. #define PTE_FILE_MAX_BITS    (64UL - PAGE_SHIFT - 1UL)
  738.  
  739. extern unsigned long prom_virt_to_phys(unsigned long, int *);
  740.  
  741. extern unsigned long sun4u_get_pte(unsigned long);
  742.  
  743. static inline unsigned long __get_phys(unsigned long addr)
  744. {
  745.     return sun4u_get_pte(addr);
  746. }
  747.  
  748. static inline int __get_iospace(unsigned long addr)
  749. {
  750.     return ((sun4u_get_pte(addr) & 0xf0000000) >> 28);
  751. }
  752.  
  753. extern unsigned long *sparc64_valid_addr_bitmap;
  754.  
  755. /* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
  756. #define kern_addr_valid(addr)    \
  757.     (test_bit(__pa((unsigned long)(addr))>>22, sparc64_valid_addr_bitmap))
  758.  
  759. extern int page_in_phys_avail(unsigned long paddr);
  760.  
  761. extern int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
  762.                    unsigned long pfn,
  763.                    unsigned long size, pgprot_t prot);
  764.  
  765. /*
  766.  * For sparc32&64, the pfn in io_remap_pfn_range() carries <iospace> in
  767.  * its high 4 bits.  These macros/functions put it there or get it from there.
  768.  */
  769. #define MK_IOSPACE_PFN(space, pfn)    (pfn | (space << (BITS_PER_LONG - 4)))
  770. #define GET_IOSPACE(pfn)        (pfn >> (BITS_PER_LONG - 4))
  771. #define GET_PFN(pfn)            (pfn & 0x0fffffffffffffffUL)
  772.  
  773. #include <asm-generic/pgtable.h>
  774.  
  775. /* We provide our own get_unmapped_area to cope with VA holes and
  776.  * SHM area cache aliasing for userland.
  777.  */
  778. #define HAVE_ARCH_UNMAPPED_AREA
  779. #define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
  780.  
  781. /* We provide a special get_unmapped_area for framebuffer mmaps to try and use
  782.  * the largest alignment possible such that larget PTEs can be used.
  783.  */
  784. extern unsigned long get_fb_unmapped_area(struct file *filp, unsigned long,
  785.                       unsigned long, unsigned long,
  786.                       unsigned long);
  787. #define HAVE_ARCH_FB_UNMAPPED_AREA
  788.  
  789. extern void pgtable_cache_init(void);
  790. extern void sun4v_register_fault_status(void);
  791. extern void sun4v_ktsb_register(void);
  792.  
  793. #endif /* !(__ASSEMBLY__) */
  794.  
  795. #endif /* !(_SPARC64_PGTABLE_H) */
  796.