1 /* $Id: pgtable.h,v 1.110 2001/12/21 04:56:17 davem Exp $ */
2 #ifndef _SPARC_PGTABLE_H
3 #define _SPARC_PGTABLE_H
5 /* asm-sparc/pgtable.h: Defines and functions used to work
6 * with Sparc page tables.
8 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
9 * Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
12 #include <linux/config.h>
13 #include <linux/spinlock.h>
14 #include <linux/swap.h>
15 #include <asm/types.h>
17 #include <asm/pgtsun4.h>
19 #include <asm/pgtsun4c.h>
21 #include <asm/pgtsrmmu.h>
22 #include <asm/vac-ops.h>
23 #include <asm/oplib.h>
25 #include <asm/btfixup.h>
26 #include <asm/system.h>
30 struct vm_area_struct;
33 extern void load_mmu(void);
34 extern unsigned long calc_highpages(void);
36 /* Routines for data transfer buffers. */
37 BTFIXUPDEF_CALL(char *, mmu_lockarea, char *, unsigned long)
38 BTFIXUPDEF_CALL(void, mmu_unlockarea, char *, unsigned long)
40 #define mmu_lockarea(vaddr,len) BTFIXUP_CALL(mmu_lockarea)(vaddr,len)
41 #define mmu_unlockarea(vaddr,len) BTFIXUP_CALL(mmu_unlockarea)(vaddr,len)
43 /* These are implementations for sbus_map_sg/sbus_unmap_sg... collapse later */
44 BTFIXUPDEF_CALL(__u32, mmu_get_scsi_one, char *, unsigned long, struct sbus_bus *sbus)
45 BTFIXUPDEF_CALL(void, mmu_get_scsi_sgl, struct scatterlist *, int, struct sbus_bus *sbus)
46 BTFIXUPDEF_CALL(void, mmu_release_scsi_one, __u32, unsigned long, struct sbus_bus *sbus)
47 BTFIXUPDEF_CALL(void, mmu_release_scsi_sgl, struct scatterlist *, int, struct sbus_bus *sbus)
49 #define mmu_get_scsi_one(vaddr,len,sbus) BTFIXUP_CALL(mmu_get_scsi_one)(vaddr,len,sbus)
50 #define mmu_get_scsi_sgl(sg,sz,sbus) BTFIXUP_CALL(mmu_get_scsi_sgl)(sg,sz,sbus)
51 #define mmu_release_scsi_one(vaddr,len,sbus) BTFIXUP_CALL(mmu_release_scsi_one)(vaddr,len,sbus)
52 #define mmu_release_scsi_sgl(sg,sz,sbus) BTFIXUP_CALL(mmu_release_scsi_sgl)(sg,sz,sbus)
55 * mmu_map/unmap are provided by iommu/iounit; Invalid to call on IIep.
57 * The mmu_map_dma_area establishes two mappings in one go.
58 * These mappings point to pages normally mapped at 'va' (linear address).
59 * First mapping is for CPU visible address at 'a', uncached.
60 * This is an alias, but it works because it is an uncached mapping.
61 * Second mapping is for device visible address, or "bus" address.
62 * The bus address is returned at '*pba'.
64 * These functions seem distinct, but are hard to split. On sun4c,
65 * at least for now, 'a' is equal to bus address, and retured in *pba.
66 * On sun4m, page attributes depend on the CPU type, so we have to
67 * know if we are mapping RAM or I/O, so it has to be an additional argument
68 * to a separate mapping function for CPU visible mappings.
70 BTFIXUPDEF_CALL(int, mmu_map_dma_area, dma_addr_t *, unsigned long, unsigned long, int len)
71 BTFIXUPDEF_CALL(struct page *, mmu_translate_dvma, unsigned long busa)
72 BTFIXUPDEF_CALL(void, mmu_unmap_dma_area, unsigned long busa, int len)
74 #define mmu_map_dma_area(pba,va,a,len) BTFIXUP_CALL(mmu_map_dma_area)(pba,va,a,len)
75 #define mmu_unmap_dma_area(ba,len) BTFIXUP_CALL(mmu_unmap_dma_area)(ba,len)
76 #define mmu_translate_dvma(ba) BTFIXUP_CALL(mmu_translate_dvma)(ba)
80 BTFIXUPDEF_SIMM13(pmd_shift)
81 BTFIXUPDEF_SETHI(pmd_size)
82 BTFIXUPDEF_SETHI(pmd_mask)
84 extern unsigned int pmd_align(unsigned int addr) __attribute_const__;
85 extern __inline__ unsigned int pmd_align(unsigned int addr)
87 return ((addr + ~BTFIXUP_SETHI(pmd_mask)) & BTFIXUP_SETHI(pmd_mask));
90 BTFIXUPDEF_SIMM13(pgdir_shift)
91 BTFIXUPDEF_SETHI(pgdir_size)
92 BTFIXUPDEF_SETHI(pgdir_mask)
94 extern unsigned int pgdir_align(unsigned int addr) __attribute_const__;
95 extern __inline__ unsigned int pgdir_align(unsigned int addr)
97 return ((addr + ~BTFIXUP_SETHI(pgdir_mask)) & BTFIXUP_SETHI(pgdir_mask));
100 BTFIXUPDEF_SIMM13(ptrs_per_pte)
101 BTFIXUPDEF_SIMM13(ptrs_per_pmd)
102 BTFIXUPDEF_SIMM13(ptrs_per_pgd)
103 BTFIXUPDEF_SIMM13(user_ptrs_per_pgd)
105 #define pte_ERROR(e) __builtin_trap()
106 #define pmd_ERROR(e) __builtin_trap()
107 #define pgd_ERROR(e) __builtin_trap()
109 BTFIXUPDEF_INT(page_none)
110 BTFIXUPDEF_INT(page_shared)
111 BTFIXUPDEF_INT(page_copy)
112 BTFIXUPDEF_INT(page_readonly)
113 BTFIXUPDEF_INT(page_kernel)
115 #define PMD_SHIFT BTFIXUP_SIMM13(pmd_shift)
116 #define PMD_SIZE BTFIXUP_SETHI(pmd_size)
117 #define PMD_MASK BTFIXUP_SETHI(pmd_mask)
118 #define PMD_ALIGN(addr) pmd_align(addr)
119 #define PGDIR_SHIFT BTFIXUP_SIMM13(pgdir_shift)
120 #define PGDIR_SIZE BTFIXUP_SETHI(pgdir_size)
121 #define PGDIR_MASK BTFIXUP_SETHI(pgdir_mask)
122 #define PGDIR_ALIGN pgdir_align(addr)
123 #define PTRS_PER_PTE BTFIXUP_SIMM13(ptrs_per_pte)
124 #define PTRS_PER_PMD BTFIXUP_SIMM13(ptrs_per_pmd)
125 #define PTRS_PER_PGD BTFIXUP_SIMM13(ptrs_per_pgd)
126 #define USER_PTRS_PER_PGD BTFIXUP_SIMM13(user_ptrs_per_pgd)
127 #define FIRST_USER_PGD_NR 0
129 #define PAGE_NONE __pgprot(BTFIXUP_INT(page_none))
130 #define PAGE_SHARED __pgprot(BTFIXUP_INT(page_shared))
131 #define PAGE_COPY __pgprot(BTFIXUP_INT(page_copy))
132 #define PAGE_READONLY __pgprot(BTFIXUP_INT(page_readonly))
134 extern unsigned long page_kernel;
137 #define PAGE_KERNEL page_kernel
139 #define PAGE_KERNEL __pgprot(BTFIXUP_INT(page_kernel))
142 /* Top-level page directory */
143 extern pgd_t swapper_pg_dir[1024];
145 /* Page table for 0-4MB for everybody, on the Sparc this
146 * holds the same as on the i386.
148 extern pte_t pg0[1024];
149 extern pte_t pg1[1024];
150 extern pte_t pg2[1024];
151 extern pte_t pg3[1024];
153 extern unsigned long ptr_in_current_pgd;
155 /* Here is a trick, since mmap.c need the initializer elements for
156 * protection_map[] to be constant at compile time, I set the following
157 * to all zeros. I set it to the real values after I link in the
158 * appropriate MMU page table routines at boot time.
160 #define __P000 __pgprot(0)
161 #define __P001 __pgprot(0)
162 #define __P010 __pgprot(0)
163 #define __P011 __pgprot(0)
164 #define __P100 __pgprot(0)
165 #define __P101 __pgprot(0)
166 #define __P110 __pgprot(0)
167 #define __P111 __pgprot(0)
169 #define __S000 __pgprot(0)
170 #define __S001 __pgprot(0)
171 #define __S010 __pgprot(0)
172 #define __S011 __pgprot(0)
173 #define __S100 __pgprot(0)
174 #define __S101 __pgprot(0)
175 #define __S110 __pgprot(0)
176 #define __S111 __pgprot(0)
178 extern int num_contexts;
180 /* First physical page can be anywhere, the following is needed so that
181 * va-->pa and vice versa conversions work properly without performance
182 * hit for all __pa()/__va() operations.
184 extern unsigned long phys_base;
185 extern unsigned long pfn_base;
188 * BAD_PAGETABLE is used when we need a bogus page-table, while
189 * BAD_PAGE is used for a bogus page.
191 * ZERO_PAGE is a global shared page that is always zero: used
192 * for zero-mapped memory areas etc..
194 extern pte_t * __bad_pagetable(void);
195 extern pte_t __bad_page(void);
196 extern unsigned long empty_zero_page;
198 #define BAD_PAGETABLE __bad_pagetable()
199 #define BAD_PAGE __bad_page()
200 #define ZERO_PAGE(vaddr) (virt_to_page(&empty_zero_page))
204 BTFIXUPDEF_CALL_CONST(struct page *, pmd_page, pmd_t)
205 BTFIXUPDEF_CALL_CONST(unsigned long, pgd_page, pgd_t)
207 #define pmd_page(pmd) BTFIXUP_CALL(pmd_page)(pmd)
208 #define pgd_page(pgd) BTFIXUP_CALL(pgd_page)(pgd)
210 BTFIXUPDEF_SETHI(none_mask)
211 BTFIXUPDEF_CALL_CONST(int, pte_present, pte_t)
212 BTFIXUPDEF_CALL(void, pte_clear, pte_t *)
214 extern __inline__ int pte_none(pte_t pte)
216 return !(pte_val(pte) & ~BTFIXUP_SETHI(none_mask));
219 #define pte_present(pte) BTFIXUP_CALL(pte_present)(pte)
220 #define pte_clear(pte) BTFIXUP_CALL(pte_clear)(pte)
222 BTFIXUPDEF_CALL_CONST(int, pmd_bad, pmd_t)
223 BTFIXUPDEF_CALL_CONST(int, pmd_present, pmd_t)
224 BTFIXUPDEF_CALL(void, pmd_clear, pmd_t *)
226 extern __inline__ int pmd_none(pmd_t pmd)
228 return !(pmd_val(pmd) & ~BTFIXUP_SETHI(none_mask));
231 #define pmd_bad(pmd) BTFIXUP_CALL(pmd_bad)(pmd)
232 #define pmd_present(pmd) BTFIXUP_CALL(pmd_present)(pmd)
233 #define pmd_clear(pmd) BTFIXUP_CALL(pmd_clear)(pmd)
235 BTFIXUPDEF_CALL_CONST(int, pgd_none, pgd_t)
236 BTFIXUPDEF_CALL_CONST(int, pgd_bad, pgd_t)
237 BTFIXUPDEF_CALL_CONST(int, pgd_present, pgd_t)
238 BTFIXUPDEF_CALL(void, pgd_clear, pgd_t *)
240 #define pgd_none(pgd) BTFIXUP_CALL(pgd_none)(pgd)
241 #define pgd_bad(pgd) BTFIXUP_CALL(pgd_bad)(pgd)
242 #define pgd_present(pgd) BTFIXUP_CALL(pgd_present)(pgd)
243 #define pgd_clear(pgd) BTFIXUP_CALL(pgd_clear)(pgd)
246 * The following only work if pte_present() is true.
247 * Undefined behaviour if not..
249 BTFIXUPDEF_HALF(pte_writei)
250 BTFIXUPDEF_HALF(pte_dirtyi)
251 BTFIXUPDEF_HALF(pte_youngi)
253 extern int pte_write(pte_t pte) __attribute_const__;
254 extern __inline__ int pte_write(pte_t pte)
256 return pte_val(pte) & BTFIXUP_HALF(pte_writei);
259 extern int pte_dirty(pte_t pte) __attribute_const__;
260 extern __inline__ int pte_dirty(pte_t pte)
262 return pte_val(pte) & BTFIXUP_HALF(pte_dirtyi);
265 extern int pte_young(pte_t pte) __attribute_const__;
266 extern __inline__ int pte_young(pte_t pte)
268 return pte_val(pte) & BTFIXUP_HALF(pte_youngi);
272 * The following only work if pte_present() is not true.
274 BTFIXUPDEF_HALF(pte_filei)
276 extern int pte_file(pte_t pte) __attribute_const__;
277 extern __inline__ int pte_file(pte_t pte)
279 return pte_val(pte) & BTFIXUP_HALF(pte_filei);
284 BTFIXUPDEF_HALF(pte_wrprotecti)
285 BTFIXUPDEF_HALF(pte_mkcleani)
286 BTFIXUPDEF_HALF(pte_mkoldi)
288 extern pte_t pte_wrprotect(pte_t pte) __attribute_const__;
289 extern __inline__ pte_t pte_wrprotect(pte_t pte)
291 return __pte(pte_val(pte) & ~BTFIXUP_HALF(pte_wrprotecti));
294 extern pte_t pte_mkclean(pte_t pte) __attribute_const__;
295 extern __inline__ pte_t pte_mkclean(pte_t pte)
297 return __pte(pte_val(pte) & ~BTFIXUP_HALF(pte_mkcleani));
300 extern pte_t pte_mkold(pte_t pte) __attribute_const__;
301 extern __inline__ pte_t pte_mkold(pte_t pte)
303 return __pte(pte_val(pte) & ~BTFIXUP_HALF(pte_mkoldi));
306 BTFIXUPDEF_CALL_CONST(pte_t, pte_mkwrite, pte_t)
307 BTFIXUPDEF_CALL_CONST(pte_t, pte_mkdirty, pte_t)
308 BTFIXUPDEF_CALL_CONST(pte_t, pte_mkyoung, pte_t)
310 #define pte_mkwrite(pte) BTFIXUP_CALL(pte_mkwrite)(pte)
311 #define pte_mkdirty(pte) BTFIXUP_CALL(pte_mkdirty)(pte)
312 #define pte_mkyoung(pte) BTFIXUP_CALL(pte_mkyoung)(pte)
314 #define page_pte_prot(page, prot) mk_pte(page, prot)
315 #define page_pte(page) mk_pte(page, __pgprot(0))
316 #define pfn_pte(pfn, prot) mk_pte(pfn_to_page(pfn), prot)
318 BTFIXUPDEF_CALL(unsigned long, pte_pfn, pte_t)
319 #define pte_pfn(pte) BTFIXUP_CALL(pte_pfn)(pte)
320 #define pte_page(pte) pfn_to_page(pte_pfn(pte))
323 * Conversion functions: convert a page and protection to a page entry,
324 * and a page entry and page directory to the page they refer to.
326 BTFIXUPDEF_CALL_CONST(pte_t, mk_pte, struct page *, pgprot_t)
328 BTFIXUPDEF_CALL_CONST(pte_t, mk_pte_phys, unsigned long, pgprot_t)
329 BTFIXUPDEF_CALL_CONST(pte_t, mk_pte_io, unsigned long, pgprot_t, int)
331 #define mk_pte(page,pgprot) BTFIXUP_CALL(mk_pte)(page,pgprot)
332 #define mk_pte_phys(page,pgprot) BTFIXUP_CALL(mk_pte_phys)(page,pgprot)
333 #define mk_pte_io(page,pgprot,space) BTFIXUP_CALL(mk_pte_io)(page,pgprot,space)
335 BTFIXUPDEF_INT(pte_modify_mask)
337 extern pte_t pte_modify(pte_t pte, pgprot_t newprot) __attribute_const__;
338 extern __inline__ pte_t pte_modify(pte_t pte, pgprot_t newprot)
340 return __pte((pte_val(pte) & BTFIXUP_INT(pte_modify_mask)) |
341 pgprot_val(newprot));
344 #define pgd_index(address) ((address) >> PGDIR_SHIFT)
346 /* to find an entry in a page-table-directory */
347 #define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address))
349 /* to find an entry in a kernel page-table-directory */
350 #define pgd_offset_k(address) pgd_offset(&init_mm, address)
352 /* Find an entry in the second-level page table.. */
353 BTFIXUPDEF_CALL(pmd_t *, pmd_offset, pgd_t *, unsigned long)
354 #define pmd_offset(dir,addr) BTFIXUP_CALL(pmd_offset)(dir,addr)
356 /* Find an entry in the third-level page table.. */
357 BTFIXUPDEF_CALL(pte_t *, pte_offset_kernel, pmd_t *, unsigned long)
358 #define pte_offset_kernel(dir,addr) BTFIXUP_CALL(pte_offset_kernel)(dir,addr)
361 * This shortcut works on sun4m (and sun4d) because the nocache area is static,
362 * and sun4c is guaranteed to have no highmem anyway.
364 #define pte_offset_map(d, a) pte_offset_kernel(d,a)
365 #define pte_offset_map_nested(d, a) pte_offset_kernel(d,a)
367 #define pte_unmap(pte) do{}while(0)
368 #define pte_unmap_nested(pte) do{}while(0)
370 /* The permissions for pgprot_val to make a page mapped on the obio space */
371 extern unsigned int pg_iobits;
373 /* Certain architectures need to do special things when pte's
374 * within a page table are directly modified. Thus, the following
375 * hook is made available.
378 BTFIXUPDEF_CALL(void, set_pte, pte_t *, pte_t)
380 #define set_pte(ptep,pteval) BTFIXUP_CALL(set_pte)(ptep,pteval)
383 BTFIXUPDEF_CALL(void, mmu_info, struct seq_file *)
385 #define mmu_info(p) BTFIXUP_CALL(mmu_info)(p)
387 /* Fault handler stuff... */
388 #define FAULT_CODE_PROT 0x1
389 #define FAULT_CODE_WRITE 0x2
390 #define FAULT_CODE_USER 0x4
392 BTFIXUPDEF_CALL(void, update_mmu_cache, struct vm_area_struct *, unsigned long, pte_t)
394 #define update_mmu_cache(vma,addr,pte) BTFIXUP_CALL(update_mmu_cache)(vma,addr,pte)
396 BTFIXUPDEF_CALL(void, sparc_mapiorange, unsigned int, unsigned long,
397 unsigned long, unsigned int)
398 BTFIXUPDEF_CALL(void, sparc_unmapiorange, unsigned long, unsigned int)
399 #define sparc_mapiorange(bus,pa,va,len) BTFIXUP_CALL(sparc_mapiorange)(bus,pa,va,len)
400 #define sparc_unmapiorange(va,len) BTFIXUP_CALL(sparc_unmapiorange)(va,len)
402 extern int invalid_segment;
404 /* Encode and de-code a swap entry */
405 BTFIXUPDEF_CALL(unsigned long, __swp_type, swp_entry_t)
406 BTFIXUPDEF_CALL(unsigned long, __swp_offset, swp_entry_t)
407 BTFIXUPDEF_CALL(swp_entry_t, __swp_entry, unsigned long, unsigned long)
409 #define __swp_type(__x) BTFIXUP_CALL(__swp_type)(__x)
410 #define __swp_offset(__x) BTFIXUP_CALL(__swp_offset)(__x)
411 #define __swp_entry(__type,__off) BTFIXUP_CALL(__swp_entry)(__type,__off)
413 #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
414 #define __swp_entry_to_pte(x) ((pte_t) { (x).val })
416 /* file-offset-in-pte helpers */
417 BTFIXUPDEF_CALL(unsigned long, pte_to_pgoff, pte_t pte);
418 BTFIXUPDEF_CALL(pte_t, pgoff_to_pte, unsigned long pgoff);
420 #define pte_to_pgoff(pte) BTFIXUP_CALL(pte_to_pgoff)(pte)
421 #define pgoff_to_pte(off) BTFIXUP_CALL(pgoff_to_pte)(off)
424 * This is made a constant because mm/fremap.c required a constant.
425 * Note that layout of these bits is different between sun4c.c and srmmu.c.
427 #define PTE_FILE_MAX_BITS 24
432 struct ctx_list *next;
433 struct ctx_list *prev;
434 unsigned int ctx_number;
435 struct mm_struct *ctx_mm;
438 extern struct ctx_list *ctx_list_pool; /* Dynamically allocated */
439 extern struct ctx_list ctx_free; /* Head of free list */
440 extern struct ctx_list ctx_used; /* Head of used contexts list */
442 #define NO_CONTEXT -1
444 extern __inline__ void remove_from_ctx_list(struct ctx_list *entry)
446 entry->next->prev = entry->prev;
447 entry->prev->next = entry->next;
450 extern __inline__ void add_to_ctx_list(struct ctx_list *head, struct ctx_list *entry)
453 (entry->prev = head->prev)->next = entry;
456 #define add_to_free_ctxlist(entry) add_to_ctx_list(&ctx_free, entry)
457 #define add_to_used_ctxlist(entry) add_to_ctx_list(&ctx_used, entry)
459 extern __inline__ unsigned long
460 __get_phys (unsigned long addr)
462 switch (sparc_cpu_model){
465 return sun4c_get_pte (addr) << PAGE_SHIFT;
468 return ((srmmu_get_pte (addr) & 0xffffff00) << 4);
474 extern __inline__ int
475 __get_iospace (unsigned long addr)
477 switch (sparc_cpu_model){
480 return -1; /* Don't check iospace on sun4c */
483 return (srmmu_get_pte (addr) >> 28);
489 extern unsigned long *sparc_valid_addr_bitmap;
491 /* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
492 #define kern_addr_valid(addr) \
493 (test_bit(__pa((unsigned long)(addr))>>20, sparc_valid_addr_bitmap))
495 extern int io_remap_page_range(struct vm_area_struct *vma, unsigned long from, unsigned long to,
496 unsigned long size, pgprot_t prot, int space);
498 #include <asm-generic/pgtable.h>
500 #endif /* !(__ASSEMBLY__) */
502 /* We provide our own get_unmapped_area to cope with VA holes for userland */
503 #define HAVE_ARCH_UNMAPPED_AREA
506 * No page table caches to initialise
508 #define pgtable_cache_init() do { } while (0)
510 #endif /* !(_SPARC_PGTABLE_H) */