aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-sparc64
diff options
context:
space:
mode:
Diffstat (limited to 'include/asm-sparc64')
-rw-r--r--include/asm-sparc64/pgtable.h266
1 files changed, 72 insertions, 194 deletions
diff --git a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h
index a480007f0a9d..bd8bce704a9f 100644
--- a/include/asm-sparc64/pgtable.h
+++ b/include/asm-sparc64/pgtable.h
@@ -90,134 +90,48 @@
90 90
91#endif /* !(__ASSEMBLY__) */ 91#endif /* !(__ASSEMBLY__) */
92 92
93/* Spitfire/Cheetah TTE bits. */ 93/* PTE bits which are the same in SUN4U and SUN4V format. */
94#define _PAGE_VALID _AC(0x8000000000000000,UL) /* Valid TTE */ 94#define _PAGE_VALID 0x8000000000000000 /* Valid TTE */
95#define _PAGE_R _AC(0x8000000000000000,UL) /* Keep ref bit up to date*/ 95#define _PAGE_R 0x8000000000000000 /* Keep ref bit up to date*/
96#define _PAGE_SZ4MB _AC(0x6000000000000000,UL) /* 4MB Page */ 96
97#define _PAGE_SZ512K _AC(0x4000000000000000,UL) /* 512K Page */ 97/* These are actually filled in at boot time by sun4{u,v}_pgprot_init() */
98#define _PAGE_SZ64K _AC(0x2000000000000000,UL) /* 64K Page */ 98#define __P000 __pgprot(0)
99#define _PAGE_SZ8K _AC(0x0000000000000000,UL) /* 8K Page */ 99#define __P001 __pgprot(0)
100#define _PAGE_NFO _AC(0x1000000000000000,UL) /* No Fault Only */ 100#define __P010 __pgprot(0)
101#define _PAGE_IE _AC(0x0800000000000000,UL) /* Invert Endianness */ 101#define __P011 __pgprot(0)
102#define _PAGE_SOFT2 _AC(0x07FC000000000000,UL) /* Software bits, set 2 */ 102#define __P100 __pgprot(0)
103#define _PAGE_RES1 _AC(0x0002000000000000,UL) /* Reserved */ 103#define __P101 __pgprot(0)
104#define _PAGE_SZ32MB _AC(0x0001000000000000,UL) /* (Panther) 32MB page */ 104#define __P110 __pgprot(0)
105#define _PAGE_SZ256MB _AC(0x2001000000000000,UL) /* (Panther) 256MB page */ 105#define __P111 __pgprot(0)
106#define _PAGE_SN _AC(0x0000800000000000,UL) /* (Cheetah) Snoop */ 106
107#define _PAGE_RES2 _AC(0x0000780000000000,UL) /* Reserved */ 107#define __S000 __pgprot(0)
108#define _PAGE_PADDR_SF _AC(0x000001FFFFFFE000,UL) /* (Spitfire) paddr[40:13]*/ 108#define __S001 __pgprot(0)
109#define _PAGE_PADDR _AC(0x000007FFFFFFE000,UL) /* (Cheetah) paddr[42:13] */ 109#define __S010 __pgprot(0)
110#define _PAGE_SOFT _AC(0x0000000000001F80,UL) /* Software bits */ 110#define __S011 __pgprot(0)
111#define _PAGE_L _AC(0x0000000000000040,UL) /* Locked TTE */ 111#define __S100 __pgprot(0)
112#define _PAGE_CP _AC(0x0000000000000020,UL) /* Cacheable in P-Cache */ 112#define __S101 __pgprot(0)
113#define _PAGE_CV _AC(0x0000000000000010,UL) /* Cacheable in V-Cache */ 113#define __S110 __pgprot(0)
114#define _PAGE_E _AC(0x0000000000000008,UL) /* side-Effect */ 114#define __S111 __pgprot(0)
115#define _PAGE_P _AC(0x0000000000000004,UL) /* Privileged Page */
116#define _PAGE_W _AC(0x0000000000000002,UL) /* Writable */
117#define _PAGE_G _AC(0x0000000000000001,UL) /* Global */
118
119#define _PAGE_ALL_SZ_BITS \
120 (_PAGE_SZ4MB | _PAGE_SZ512K | _PAGE_SZ64K | \
121 _PAGE_SZ8K | _PAGE_SZ32MB | _PAGE_SZ256MB)
122
123/* Here are the SpitFire software bits we use in the TTE's.
124 *
125 * WARNING: If you are going to try and start using some
126 * of the soft2 bits, you will need to make
127 * modifications to the swap entry implementation.
128 * For example, one thing that could happen is that
129 * swp_entry_to_pte() would BUG_ON() if you tried
130 * to use one of the soft2 bits for _PAGE_FILE.
131 *
132 * Like other architectures, I have aliased _PAGE_FILE with
133 * _PAGE_MODIFIED. This works because _PAGE_FILE is never
134 * interpreted that way unless _PAGE_PRESENT is clear.
135 */
136#define _PAGE_EXEC _AC(0x0000000000001000,UL) /* Executable SW bit */
137#define _PAGE_MODIFIED _AC(0x0000000000000800,UL) /* Modified (dirty) */
138#define _PAGE_FILE _AC(0x0000000000000800,UL) /* Pagecache page */
139#define _PAGE_ACCESSED _AC(0x0000000000000400,UL) /* Accessed (ref'd) */
140#define _PAGE_READ _AC(0x0000000000000200,UL) /* Readable SW Bit */
141#define _PAGE_WRITE _AC(0x0000000000000100,UL) /* Writable SW Bit */
142#define _PAGE_PRESENT _AC(0x0000000000000080,UL) /* Present */
143
144#if PAGE_SHIFT == 13
145#define _PAGE_SZBITS _PAGE_SZ8K
146#elif PAGE_SHIFT == 16
147#define _PAGE_SZBITS _PAGE_SZ64K
148#elif PAGE_SHIFT == 19
149#define _PAGE_SZBITS _PAGE_SZ512K
150#elif PAGE_SHIFT == 22
151#define _PAGE_SZBITS _PAGE_SZ4MB
152#else
153#error Wrong PAGE_SHIFT specified
154#endif
155
156#if defined(CONFIG_HUGETLB_PAGE_SIZE_4MB)
157#define _PAGE_SZHUGE _PAGE_SZ4MB
158#elif defined(CONFIG_HUGETLB_PAGE_SIZE_512K)
159#define _PAGE_SZHUGE _PAGE_SZ512K
160#elif defined(CONFIG_HUGETLB_PAGE_SIZE_64K)
161#define _PAGE_SZHUGE _PAGE_SZ64K
162#endif
163
164#define _PAGE_CACHE (_PAGE_CP | _PAGE_CV)
165
166#define __DIRTY_BITS (_PAGE_MODIFIED | _PAGE_WRITE | _PAGE_W)
167#define __ACCESS_BITS (_PAGE_ACCESSED | _PAGE_READ | _PAGE_R)
168#define __PRIV_BITS _PAGE_P
169
170#define PAGE_NONE __pgprot (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_CACHE)
171
172/* Don't set the TTE _PAGE_W bit here, else the dirty bit never gets set. */
173#define PAGE_SHARED __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
174 __ACCESS_BITS | _PAGE_WRITE | _PAGE_EXEC)
175
176#define PAGE_COPY __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
177 __ACCESS_BITS | _PAGE_EXEC)
178
179#define PAGE_READONLY __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
180 __ACCESS_BITS | _PAGE_EXEC)
181
182#define PAGE_KERNEL __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
183 __PRIV_BITS | \
184 __ACCESS_BITS | __DIRTY_BITS | _PAGE_EXEC)
185
186#define PAGE_SHARED_NOEXEC __pgprot (_PAGE_PRESENT | _PAGE_VALID | \
187 _PAGE_CACHE | \
188 __ACCESS_BITS | _PAGE_WRITE)
189
190#define PAGE_COPY_NOEXEC __pgprot (_PAGE_PRESENT | _PAGE_VALID | \
191 _PAGE_CACHE | __ACCESS_BITS)
192
193#define PAGE_READONLY_NOEXEC __pgprot (_PAGE_PRESENT | _PAGE_VALID | \
194 _PAGE_CACHE | __ACCESS_BITS)
195
196#define _PFN_MASK _PAGE_PADDR
197
198#define pg_iobits (_PAGE_VALID | _PAGE_PRESENT | __DIRTY_BITS | \
199 __ACCESS_BITS | _PAGE_E)
200
201#define __P000 PAGE_NONE
202#define __P001 PAGE_READONLY_NOEXEC
203#define __P010 PAGE_COPY_NOEXEC
204#define __P011 PAGE_COPY_NOEXEC
205#define __P100 PAGE_READONLY
206#define __P101 PAGE_READONLY
207#define __P110 PAGE_COPY
208#define __P111 PAGE_COPY
209
210#define __S000 PAGE_NONE
211#define __S001 PAGE_READONLY_NOEXEC
212#define __S010 PAGE_SHARED_NOEXEC
213#define __S011 PAGE_SHARED_NOEXEC
214#define __S100 PAGE_READONLY
215#define __S101 PAGE_READONLY
216#define __S110 PAGE_SHARED
217#define __S111 PAGE_SHARED
218 115
219#ifndef __ASSEMBLY__ 116#ifndef __ASSEMBLY__
220 117
118extern pte_t mk_pte_io(unsigned long, pgprot_t, int, unsigned long);
119
120extern unsigned long pte_sz_bits(unsigned long size);
121
122extern pgprot_t PAGE_KERNEL;
123extern pgprot_t PAGE_KERNEL_LOCKED;
124extern pgprot_t PAGE_COPY;
125
126/* XXX This uglyness is for the atyfb driver's sparc mmap() support. XXX */
127extern unsigned long _PAGE_IE;
128extern unsigned long _PAGE_E;
129extern unsigned long _PAGE_CACHE;
130
131extern unsigned long pg_iobits;
132extern unsigned long _PAGE_ALL_SZ_BITS;
133extern unsigned long _PAGE_SZBITS;
134
221extern unsigned long phys_base; 135extern unsigned long phys_base;
222extern unsigned long pfn_base; 136extern unsigned long pfn_base;
223 137
@@ -229,27 +143,12 @@ extern struct page *mem_map_zero;
229 * the first physical page in the machine is at some huge physical address, 143 * the first physical page in the machine is at some huge physical address,
230 * such as 4GB. This is common on a partitioned E10000, for example. 144 * such as 4GB. This is common on a partitioned E10000, for example.
231 */ 145 */
232 146extern pte_t pfn_pte(unsigned long, pgprot_t);
233#define pfn_pte(pfn, prot) \
234 __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot) | _PAGE_SZBITS)
235#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot)) 147#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot))
148extern unsigned long pte_pfn(pte_t);
149#define pte_page(x) pfn_to_page(pte_pfn(x))
150extern pte_t pte_modify(pte_t, pgprot_t);
236 151
237#define pte_pfn(x) ((pte_val(x) & _PAGE_PADDR)>>PAGE_SHIFT)
238#define pte_page(x) pfn_to_page(pte_pfn(x))
239
240static inline pte_t pte_modify(pte_t orig_pte, pgprot_t new_prot)
241{
242 pte_t __pte;
243 const unsigned long preserve_mask = (_PFN_MASK |
244 _PAGE_MODIFIED | _PAGE_ACCESSED |
245 _PAGE_CACHE | _PAGE_E |
246 _PAGE_PRESENT | _PAGE_SZBITS);
247
248 pte_val(__pte) = (pte_val(orig_pte) & preserve_mask) |
249 (pgprot_val(new_prot) & ~preserve_mask);
250
251 return __pte;
252}
253#define pmd_set(pmdp, ptep) \ 152#define pmd_set(pmdp, ptep) \
254 (pmd_val(*(pmdp)) = (__pa((unsigned long) (ptep)) >> 11UL)) 153 (pmd_val(*(pmdp)) = (__pa((unsigned long) (ptep)) >> 11UL))
255#define pud_set(pudp, pmdp) \ 154#define pud_set(pudp, pmdp) \
@@ -259,8 +158,6 @@ static inline pte_t pte_modify(pte_t orig_pte, pgprot_t new_prot)
259#define pmd_page(pmd) virt_to_page((void *)__pmd_page(pmd)) 158#define pmd_page(pmd) virt_to_page((void *)__pmd_page(pmd))
260#define pud_page(pud) \ 159#define pud_page(pud) \
261 ((unsigned long) __va((((unsigned long)pud_val(pud))<<11UL))) 160 ((unsigned long) __va((((unsigned long)pud_val(pud))<<11UL)))
262#define pte_none(pte) (!pte_val(pte))
263#define pte_present(pte) (pte_val(pte) & _PAGE_PRESENT)
264#define pmd_none(pmd) (!pmd_val(pmd)) 161#define pmd_none(pmd) (!pmd_val(pmd))
265#define pmd_bad(pmd) (0) 162#define pmd_bad(pmd) (0)
266#define pmd_present(pmd) (pmd_val(pmd) != 0U) 163#define pmd_present(pmd) (pmd_val(pmd) != 0U)
@@ -270,30 +167,29 @@ static inline pte_t pte_modify(pte_t orig_pte, pgprot_t new_prot)
270#define pud_present(pud) (pud_val(pud) != 0U) 167#define pud_present(pud) (pud_val(pud) != 0U)
271#define pud_clear(pudp) (pud_val(*(pudp)) = 0U) 168#define pud_clear(pudp) (pud_val(*(pudp)) = 0U)
272 169
170/* Same in both SUN4V and SUN4U. */
171#define pte_none(pte) (!pte_val(pte))
172
173extern unsigned long pte_present(pte_t);
174
273/* The following only work if pte_present() is true. 175/* The following only work if pte_present() is true.
274 * Undefined behaviour if not.. 176 * Undefined behaviour if not..
275 */ 177 */
276#define pte_read(pte) (pte_val(pte) & _PAGE_READ) 178extern unsigned long pte_read(pte_t);
277#define pte_exec(pte) (pte_val(pte) & _PAGE_EXEC) 179extern unsigned long pte_exec(pte_t);
278#define pte_write(pte) (pte_val(pte) & _PAGE_WRITE) 180extern unsigned long pte_write(pte_t);
279#define pte_dirty(pte) (pte_val(pte) & _PAGE_MODIFIED) 181extern unsigned long pte_dirty(pte_t);
280#define pte_young(pte) (pte_val(pte) & _PAGE_ACCESSED) 182extern unsigned long pte_young(pte_t);
281#define pte_wrprotect(pte) (__pte(pte_val(pte) & ~(_PAGE_WRITE|_PAGE_W))) 183extern pte_t pte_wrprotect(pte_t);
282#define pte_rdprotect(pte) \ 184extern pte_t pte_rdprotect(pte_t);
283 (__pte(((pte_val(pte)<<1UL)>>1UL) & ~_PAGE_READ)) 185extern pte_t pte_mkclean(pte_t);
284#define pte_mkclean(pte) \ 186extern pte_t pte_mkold(pte_t);
285 (__pte(pte_val(pte) & ~(_PAGE_MODIFIED|_PAGE_W)))
286#define pte_mkold(pte) \
287 (__pte(((pte_val(pte)<<1UL)>>1UL) & ~_PAGE_ACCESSED))
288
289/* Permanent address of a page. */
290#define __page_address(page) page_address(page)
291 187
292/* Be very careful when you change these three, they are delicate. */ 188/* Be very careful when you change these three, they are delicate. */
293#define pte_mkyoung(pte) (__pte(pte_val(pte) | _PAGE_ACCESSED | _PAGE_R)) 189extern pte_t pte_mkyoung(pte_t);
294#define pte_mkwrite(pte) (__pte(pte_val(pte) | _PAGE_WRITE)) 190extern pte_t pte_mkwrite(pte_t);
295#define pte_mkdirty(pte) (__pte(pte_val(pte) | _PAGE_MODIFIED | _PAGE_W)) 191extern pte_t pte_mkdirty(pte_t);
296#define pte_mkhuge(pte) (__pte(pte_val(pte) | _PAGE_SZHUGE)) 192extern pte_t pte_mkhuge(pte_t);
297 193
298/* to find an entry in a page-table-directory. */ 194/* to find an entry in a page-table-directory. */
299#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1)) 195#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1))
@@ -328,6 +224,9 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *p
328 224
329 /* It is more efficient to let flush_tlb_kernel_range() 225 /* It is more efficient to let flush_tlb_kernel_range()
330 * handle init_mm tlb flushes. 226 * handle init_mm tlb flushes.
227 *
228 * SUN4V NOTE: _PAGE_VALID is the same value in both the SUN4U
229 * and SUN4V pte layout, so this inline test is fine.
331 */ 230 */
332 if (likely(mm != &init_mm) && (pte_val(orig) & _PAGE_VALID)) 231 if (likely(mm != &init_mm) && (pte_val(orig) & _PAGE_VALID))
333 tlb_batch_add(mm, addr, ptep, orig); 232 tlb_batch_add(mm, addr, ptep, orig);
@@ -362,42 +261,23 @@ extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t);
362#define __swp_entry_to_pte(x) ((pte_t) { (x).val }) 261#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
363 262
364/* File offset in PTE support. */ 263/* File offset in PTE support. */
365#define pte_file(pte) (pte_val(pte) & _PAGE_FILE) 264extern unsigned long pte_file(pte_t);
366#define pte_to_pgoff(pte) (pte_val(pte) >> PAGE_SHIFT) 265#define pte_to_pgoff(pte) (pte_val(pte) >> PAGE_SHIFT)
367#define pgoff_to_pte(off) (__pte(((off) << PAGE_SHIFT) | _PAGE_FILE)) 266extern pte_t pgoff_to_pte(unsigned long);
368#define PTE_FILE_MAX_BITS (64UL - PAGE_SHIFT - 1UL) 267#define PTE_FILE_MAX_BITS (64UL - PAGE_SHIFT - 1UL)
369 268
370extern unsigned long prom_virt_to_phys(unsigned long, int *); 269extern unsigned long prom_virt_to_phys(unsigned long, int *);
371 270
372static __inline__ unsigned long 271extern unsigned long sun4u_get_pte(unsigned long);
373sun4u_get_pte (unsigned long addr)
374{
375 pgd_t *pgdp;
376 pud_t *pudp;
377 pmd_t *pmdp;
378 pte_t *ptep;
379
380 if (addr >= PAGE_OFFSET)
381 return addr & _PAGE_PADDR;
382 if ((addr >= LOW_OBP_ADDRESS) && (addr < HI_OBP_ADDRESS))
383 return prom_virt_to_phys(addr, NULL);
384 pgdp = pgd_offset_k(addr);
385 pudp = pud_offset(pgdp, addr);
386 pmdp = pmd_offset(pudp, addr);
387 ptep = pte_offset_kernel(pmdp, addr);
388 return pte_val(*ptep) & _PAGE_PADDR;
389}
390 272
391static __inline__ unsigned long 273static inline unsigned long __get_phys(unsigned long addr)
392__get_phys (unsigned long addr)
393{ 274{
394 return sun4u_get_pte (addr); 275 return sun4u_get_pte(addr);
395} 276}
396 277
397static __inline__ int 278static inline int __get_iospace(unsigned long addr)
398__get_iospace (unsigned long addr)
399{ 279{
400 return ((sun4u_get_pte (addr) & 0xf0000000) >> 28); 280 return ((sun4u_get_pte(addr) & 0xf0000000) >> 28);
401} 281}
402 282
403extern unsigned long *sparc64_valid_addr_bitmap; 283extern unsigned long *sparc64_valid_addr_bitmap;
@@ -411,9 +291,7 @@ extern int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
411 unsigned long size, pgprot_t prot); 291 unsigned long size, pgprot_t prot);
412 292
413/* Clear virtual and physical cachability, set side-effect bit. */ 293/* Clear virtual and physical cachability, set side-effect bit. */
414#define pgprot_noncached(prot) \ 294extern pgprot_t pgprot_noncached(pgprot_t);
415 (__pgprot((pgprot_val(prot) & ~(_PAGE_CP | _PAGE_CV)) | \
416 _PAGE_E))
417 295
418/* 296/*
419 * For sparc32&64, the pfn in io_remap_pfn_range() carries <iospace> in 297 * For sparc32&64, the pfn in io_remap_pfn_range() carries <iospace> in