• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/arch/sparc/include/asm/
1#ifndef _SPARC_PGTABLE_H
2#define _SPARC_PGTABLE_H
3
4/*  asm/pgtable.h:  Defines and functions used to work
5 *                        with Sparc page tables.
6 *
7 *  Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
8 *  Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
9 */
10
11#ifndef __ASSEMBLY__
12#include <asm-generic/4level-fixup.h>
13
14#include <linux/spinlock.h>
15#include <linux/swap.h>
16#include <asm/types.h>
17#include <asm/pgtsun4c.h>
18#include <asm/pgtsrmmu.h>
19#include <asm/vac-ops.h>
20#include <asm/oplib.h>
21#include <asm/btfixup.h>
22#include <asm/system.h>
23
24
25struct vm_area_struct;
26struct page;
27
28extern void load_mmu(void);
29extern unsigned long calc_highpages(void);
30
31BTFIXUPDEF_SIMM13(pgdir_shift)
32BTFIXUPDEF_SETHI(pgdir_size)
33BTFIXUPDEF_SETHI(pgdir_mask)
34
35BTFIXUPDEF_SIMM13(ptrs_per_pmd)
36BTFIXUPDEF_SIMM13(ptrs_per_pgd)
37BTFIXUPDEF_SIMM13(user_ptrs_per_pgd)
38
39#define pte_ERROR(e)   __builtin_trap()
40#define pmd_ERROR(e)   __builtin_trap()
41#define pgd_ERROR(e)   __builtin_trap()
42
43BTFIXUPDEF_INT(page_none)
44BTFIXUPDEF_INT(page_copy)
45BTFIXUPDEF_INT(page_readonly)
46BTFIXUPDEF_INT(page_kernel)
47
48#define PMD_SHIFT		SUN4C_PMD_SHIFT
49#define PMD_SIZE        	(1UL << PMD_SHIFT)
50#define PMD_MASK        	(~(PMD_SIZE-1))
51#define PMD_ALIGN(__addr) 	(((__addr) + ~PMD_MASK) & PMD_MASK)
52#define PGDIR_SHIFT     	BTFIXUP_SIMM13(pgdir_shift)
53#define PGDIR_SIZE      	BTFIXUP_SETHI(pgdir_size)
54#define PGDIR_MASK      	BTFIXUP_SETHI(pgdir_mask)
55#define PTRS_PER_PTE    	1024
56#define PTRS_PER_PMD    	BTFIXUP_SIMM13(ptrs_per_pmd)
57#define PTRS_PER_PGD    	BTFIXUP_SIMM13(ptrs_per_pgd)
58#define USER_PTRS_PER_PGD	BTFIXUP_SIMM13(user_ptrs_per_pgd)
59#define FIRST_USER_ADDRESS	0
60#define PTE_SIZE		(PTRS_PER_PTE*4)
61
62#define PAGE_NONE      __pgprot(BTFIXUP_INT(page_none))
63extern pgprot_t PAGE_SHARED;
64#define PAGE_COPY      __pgprot(BTFIXUP_INT(page_copy))
65#define PAGE_READONLY  __pgprot(BTFIXUP_INT(page_readonly))
66
67extern unsigned long page_kernel;
68
69#ifdef MODULE
70#define PAGE_KERNEL	page_kernel
71#else
72#define PAGE_KERNEL    __pgprot(BTFIXUP_INT(page_kernel))
73#endif
74
75/* Top-level page directory */
76extern pgd_t swapper_pg_dir[1024];
77
78extern void paging_init(void);
79
80/* Page table for 0-4MB for everybody, on the Sparc this
81 * holds the same as on the i386.
82 */
83extern pte_t pg0[1024];
84extern pte_t pg1[1024];
85extern pte_t pg2[1024];
86extern pte_t pg3[1024];
87
88extern unsigned long ptr_in_current_pgd;
89
90/* Here is a trick, since mmap.c need the initializer elements for
91 * protection_map[] to be constant at compile time, I set the following
92 * to all zeros.  I set it to the real values after I link in the
93 * appropriate MMU page table routines at boot time.
94 */
95#define __P000  __pgprot(0)
96#define __P001  __pgprot(0)
97#define __P010  __pgprot(0)
98#define __P011  __pgprot(0)
99#define __P100  __pgprot(0)
100#define __P101  __pgprot(0)
101#define __P110  __pgprot(0)
102#define __P111  __pgprot(0)
103
104#define __S000	__pgprot(0)
105#define __S001	__pgprot(0)
106#define __S010	__pgprot(0)
107#define __S011	__pgprot(0)
108#define __S100	__pgprot(0)
109#define __S101	__pgprot(0)
110#define __S110	__pgprot(0)
111#define __S111	__pgprot(0)
112
113extern int num_contexts;
114
115/* First physical page can be anywhere, the following is needed so that
116 * va-->pa and vice versa conversions work properly without performance
117 * hit for all __pa()/__va() operations.
118 */
119extern unsigned long phys_base;
120extern unsigned long pfn_base;
121
122/*
123 * BAD_PAGETABLE is used when we need a bogus page-table, while
124 * BAD_PAGE is used for a bogus page.
125 *
126 * ZERO_PAGE is a global shared page that is always zero: used
127 * for zero-mapped memory areas etc..
128 */
129extern pte_t * __bad_pagetable(void);
130extern pte_t __bad_page(void);
131extern unsigned long empty_zero_page;
132
133#define BAD_PAGETABLE __bad_pagetable()
134#define BAD_PAGE __bad_page()
135#define ZERO_PAGE(vaddr) (virt_to_page(&empty_zero_page))
136
137/*
138 */
139BTFIXUPDEF_CALL_CONST(struct page *, pmd_page, pmd_t)
140BTFIXUPDEF_CALL_CONST(unsigned long, pgd_page_vaddr, pgd_t)
141
142#define pmd_page(pmd) BTFIXUP_CALL(pmd_page)(pmd)
143#define pgd_page_vaddr(pgd) BTFIXUP_CALL(pgd_page_vaddr)(pgd)
144
145BTFIXUPDEF_CALL_CONST(int, pte_present, pte_t)
146BTFIXUPDEF_CALL(void, pte_clear, pte_t *)
147
148static inline int pte_none(pte_t pte)
149{
150	return !pte_val(pte);
151}
152
153#define pte_present(pte) BTFIXUP_CALL(pte_present)(pte)
154#define pte_clear(mm,addr,pte) BTFIXUP_CALL(pte_clear)(pte)
155
156BTFIXUPDEF_CALL_CONST(int, pmd_bad, pmd_t)
157BTFIXUPDEF_CALL_CONST(int, pmd_present, pmd_t)
158BTFIXUPDEF_CALL(void, pmd_clear, pmd_t *)
159
160static inline int pmd_none(pmd_t pmd)
161{
162	return !pmd_val(pmd);
163}
164
165#define pmd_bad(pmd) BTFIXUP_CALL(pmd_bad)(pmd)
166#define pmd_present(pmd) BTFIXUP_CALL(pmd_present)(pmd)
167#define pmd_clear(pmd) BTFIXUP_CALL(pmd_clear)(pmd)
168
169BTFIXUPDEF_CALL_CONST(int, pgd_none, pgd_t)
170BTFIXUPDEF_CALL_CONST(int, pgd_bad, pgd_t)
171BTFIXUPDEF_CALL_CONST(int, pgd_present, pgd_t)
172BTFIXUPDEF_CALL(void, pgd_clear, pgd_t *)
173
174#define pgd_none(pgd) BTFIXUP_CALL(pgd_none)(pgd)
175#define pgd_bad(pgd) BTFIXUP_CALL(pgd_bad)(pgd)
176#define pgd_present(pgd) BTFIXUP_CALL(pgd_present)(pgd)
177#define pgd_clear(pgd) BTFIXUP_CALL(pgd_clear)(pgd)
178
179/*
180 * The following only work if pte_present() is true.
181 * Undefined behaviour if not..
182 */
183BTFIXUPDEF_HALF(pte_writei)
184BTFIXUPDEF_HALF(pte_dirtyi)
185BTFIXUPDEF_HALF(pte_youngi)
186
187static int pte_write(pte_t pte) __attribute_const__;
188static inline int pte_write(pte_t pte)
189{
190	return pte_val(pte) & BTFIXUP_HALF(pte_writei);
191}
192
193static int pte_dirty(pte_t pte) __attribute_const__;
194static inline int pte_dirty(pte_t pte)
195{
196	return pte_val(pte) & BTFIXUP_HALF(pte_dirtyi);
197}
198
199static int pte_young(pte_t pte) __attribute_const__;
200static inline int pte_young(pte_t pte)
201{
202	return pte_val(pte) & BTFIXUP_HALF(pte_youngi);
203}
204
205/*
206 * The following only work if pte_present() is not true.
207 */
208BTFIXUPDEF_HALF(pte_filei)
209
210static int pte_file(pte_t pte) __attribute_const__;
211static inline int pte_file(pte_t pte)
212{
213	return pte_val(pte) & BTFIXUP_HALF(pte_filei);
214}
215
216static inline int pte_special(pte_t pte)
217{
218	return 0;
219}
220
221/*
222 */
223BTFIXUPDEF_HALF(pte_wrprotecti)
224BTFIXUPDEF_HALF(pte_mkcleani)
225BTFIXUPDEF_HALF(pte_mkoldi)
226
227static pte_t pte_wrprotect(pte_t pte) __attribute_const__;
228static inline pte_t pte_wrprotect(pte_t pte)
229{
230	return __pte(pte_val(pte) & ~BTFIXUP_HALF(pte_wrprotecti));
231}
232
233static pte_t pte_mkclean(pte_t pte) __attribute_const__;
234static inline pte_t pte_mkclean(pte_t pte)
235{
236	return __pte(pte_val(pte) & ~BTFIXUP_HALF(pte_mkcleani));
237}
238
239static pte_t pte_mkold(pte_t pte) __attribute_const__;
240static inline pte_t pte_mkold(pte_t pte)
241{
242	return __pte(pte_val(pte) & ~BTFIXUP_HALF(pte_mkoldi));
243}
244
245BTFIXUPDEF_CALL_CONST(pte_t, pte_mkwrite, pte_t)
246BTFIXUPDEF_CALL_CONST(pte_t, pte_mkdirty, pte_t)
247BTFIXUPDEF_CALL_CONST(pte_t, pte_mkyoung, pte_t)
248
249#define pte_mkwrite(pte) BTFIXUP_CALL(pte_mkwrite)(pte)
250#define pte_mkdirty(pte) BTFIXUP_CALL(pte_mkdirty)(pte)
251#define pte_mkyoung(pte) BTFIXUP_CALL(pte_mkyoung)(pte)
252
253#define pte_mkspecial(pte)    (pte)
254
255#define pfn_pte(pfn, prot)		mk_pte(pfn_to_page(pfn), prot)
256
257BTFIXUPDEF_CALL(unsigned long,	 pte_pfn, pte_t)
258#define pte_pfn(pte) BTFIXUP_CALL(pte_pfn)(pte)
259#define pte_page(pte)	pfn_to_page(pte_pfn(pte))
260
261/*
262 * Conversion functions: convert a page and protection to a page entry,
263 * and a page entry and page directory to the page they refer to.
264 */
265BTFIXUPDEF_CALL_CONST(pte_t, mk_pte, struct page *, pgprot_t)
266
267BTFIXUPDEF_CALL_CONST(pte_t, mk_pte_phys, unsigned long, pgprot_t)
268BTFIXUPDEF_CALL_CONST(pte_t, mk_pte_io, unsigned long, pgprot_t, int)
269BTFIXUPDEF_CALL_CONST(pgprot_t, pgprot_noncached, pgprot_t)
270
271#define mk_pte(page,pgprot) BTFIXUP_CALL(mk_pte)(page,pgprot)
272#define mk_pte_phys(page,pgprot) BTFIXUP_CALL(mk_pte_phys)(page,pgprot)
273#define mk_pte_io(page,pgprot,space) BTFIXUP_CALL(mk_pte_io)(page,pgprot,space)
274
275#define pgprot_noncached(pgprot) BTFIXUP_CALL(pgprot_noncached)(pgprot)
276
277BTFIXUPDEF_INT(pte_modify_mask)
278
279static pte_t pte_modify(pte_t pte, pgprot_t newprot) __attribute_const__;
280static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
281{
282	return __pte((pte_val(pte) & BTFIXUP_INT(pte_modify_mask)) |
283		pgprot_val(newprot));
284}
285
286#define pgd_index(address) ((address) >> PGDIR_SHIFT)
287
288/* to find an entry in a page-table-directory */
289#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address))
290
291/* to find an entry in a kernel page-table-directory */
292#define pgd_offset_k(address) pgd_offset(&init_mm, address)
293
294/* Find an entry in the second-level page table.. */
295BTFIXUPDEF_CALL(pmd_t *, pmd_offset, pgd_t *, unsigned long)
296#define pmd_offset(dir,addr) BTFIXUP_CALL(pmd_offset)(dir,addr)
297
298/* Find an entry in the third-level page table.. */
299BTFIXUPDEF_CALL(pte_t *, pte_offset_kernel, pmd_t *, unsigned long)
300#define pte_offset_kernel(dir,addr) BTFIXUP_CALL(pte_offset_kernel)(dir,addr)
301
302/*
303 * This shortcut works on sun4m (and sun4d) because the nocache area is static,
304 * and sun4c is guaranteed to have no highmem anyway.
305 */
306#define pte_offset_map(d, a)		pte_offset_kernel(d,a)
307#define pte_offset_map_nested(d, a)	pte_offset_kernel(d,a)
308
309#define pte_unmap(pte)		do{}while(0)
310#define pte_unmap_nested(pte)	do{}while(0)
311
312/* Certain architectures need to do special things when pte's
313 * within a page table are directly modified.  Thus, the following
314 * hook is made available.
315 */
316
317BTFIXUPDEF_CALL(void, set_pte, pte_t *, pte_t)
318
319#define set_pte(ptep,pteval) BTFIXUP_CALL(set_pte)(ptep,pteval)
320#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval)
321
322struct seq_file;
323BTFIXUPDEF_CALL(void, mmu_info, struct seq_file *)
324
325#define mmu_info(p) BTFIXUP_CALL(mmu_info)(p)
326
327/* Fault handler stuff... */
328#define FAULT_CODE_PROT     0x1
329#define FAULT_CODE_WRITE    0x2
330#define FAULT_CODE_USER     0x4
331
332BTFIXUPDEF_CALL(void, update_mmu_cache, struct vm_area_struct *, unsigned long, pte_t *)
333
334#define update_mmu_cache(vma,addr,ptep) BTFIXUP_CALL(update_mmu_cache)(vma,addr,ptep)
335
336BTFIXUPDEF_CALL(void, sparc_mapiorange, unsigned int, unsigned long,
337    unsigned long, unsigned int)
338BTFIXUPDEF_CALL(void, sparc_unmapiorange, unsigned long, unsigned int)
339#define sparc_mapiorange(bus,pa,va,len) BTFIXUP_CALL(sparc_mapiorange)(bus,pa,va,len)
340#define sparc_unmapiorange(va,len) BTFIXUP_CALL(sparc_unmapiorange)(va,len)
341
342extern int invalid_segment;
343
344/* Encode and de-code a swap entry */
345BTFIXUPDEF_CALL(unsigned long, __swp_type, swp_entry_t)
346BTFIXUPDEF_CALL(unsigned long, __swp_offset, swp_entry_t)
347BTFIXUPDEF_CALL(swp_entry_t, __swp_entry, unsigned long, unsigned long)
348
349#define __swp_type(__x)			BTFIXUP_CALL(__swp_type)(__x)
350#define __swp_offset(__x)		BTFIXUP_CALL(__swp_offset)(__x)
351#define __swp_entry(__type,__off)	BTFIXUP_CALL(__swp_entry)(__type,__off)
352
353#define __pte_to_swp_entry(pte)		((swp_entry_t) { pte_val(pte) })
354#define __swp_entry_to_pte(x)		((pte_t) { (x).val })
355
356/* file-offset-in-pte helpers */
357BTFIXUPDEF_CALL(unsigned long, pte_to_pgoff, pte_t pte);
358BTFIXUPDEF_CALL(pte_t, pgoff_to_pte, unsigned long pgoff);
359
360#define pte_to_pgoff(pte) BTFIXUP_CALL(pte_to_pgoff)(pte)
361#define pgoff_to_pte(off) BTFIXUP_CALL(pgoff_to_pte)(off)
362
363/*
364 * This is made a constant because mm/fremap.c required a constant.
365 * Note that layout of these bits is different between sun4c.c and srmmu.c.
366 */
367#define PTE_FILE_MAX_BITS 24
368
369/*
370 */
371struct ctx_list {
372	struct ctx_list *next;
373	struct ctx_list *prev;
374	unsigned int ctx_number;
375	struct mm_struct *ctx_mm;
376};
377
378extern struct ctx_list *ctx_list_pool;  /* Dynamically allocated */
379extern struct ctx_list ctx_free;        /* Head of free list */
380extern struct ctx_list ctx_used;        /* Head of used contexts list */
381
382#define NO_CONTEXT     -1
383
384static inline void remove_from_ctx_list(struct ctx_list *entry)
385{
386	entry->next->prev = entry->prev;
387	entry->prev->next = entry->next;
388}
389
390static inline void add_to_ctx_list(struct ctx_list *head, struct ctx_list *entry)
391{
392	entry->next = head;
393	(entry->prev = head->prev)->next = entry;
394	head->prev = entry;
395}
396#define add_to_free_ctxlist(entry) add_to_ctx_list(&ctx_free, entry)
397#define add_to_used_ctxlist(entry) add_to_ctx_list(&ctx_used, entry)
398
399static inline unsigned long
400__get_phys (unsigned long addr)
401{
402	switch (sparc_cpu_model){
403	case sun4:
404	case sun4c:
405		return sun4c_get_pte (addr) << PAGE_SHIFT;
406	case sun4m:
407	case sun4d:
408		return ((srmmu_get_pte (addr) & 0xffffff00) << 4);
409	default:
410		return 0;
411	}
412}
413
414static inline int
415__get_iospace (unsigned long addr)
416{
417	switch (sparc_cpu_model){
418	case sun4:
419	case sun4c:
420		return -1; /* Don't check iospace on sun4c */
421	case sun4m:
422	case sun4d:
423		return (srmmu_get_pte (addr) >> 28);
424	default:
425		return -1;
426	}
427}
428
429extern unsigned long *sparc_valid_addr_bitmap;
430
431/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
432#define kern_addr_valid(addr) \
433	(test_bit(__pa((unsigned long)(addr))>>20, sparc_valid_addr_bitmap))
434
435extern int io_remap_pfn_range(struct vm_area_struct *vma,
436			      unsigned long from, unsigned long pfn,
437			      unsigned long size, pgprot_t prot);
438
439/*
440 * For sparc32&64, the pfn in io_remap_pfn_range() carries <iospace> in
441 * its high 4 bits.  These macros/functions put it there or get it from there.
442 */
443#define MK_IOSPACE_PFN(space, pfn)	(pfn | (space << (BITS_PER_LONG - 4)))
444#define GET_IOSPACE(pfn)		(pfn >> (BITS_PER_LONG - 4))
445#define GET_PFN(pfn)			(pfn & 0x0fffffffUL)
446
447#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
448#define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
449({									  \
450	int __changed = !pte_same(*(__ptep), __entry);			  \
451	if (__changed) {						  \
452		set_pte_at((__vma)->vm_mm, (__address), __ptep, __entry); \
453		flush_tlb_page(__vma, __address);			  \
454	}								  \
455	(sparc_cpu_model == sun4c) || __changed;			  \
456})
457
458#include <asm-generic/pgtable.h>
459
460#endif /* !(__ASSEMBLY__) */
461
462#define VMALLOC_START           0xfe600000
463#define VMALLOC_END             0xffc00000
464
465
466/* We provide our own get_unmapped_area to cope with VA holes for userland */
467#define HAVE_ARCH_UNMAPPED_AREA
468
469/*
470 * No page table caches to initialise
471 */
472#define pgtable_cache_init()	do { } while (0)
473
474#endif /* !(_SPARC_PGTABLE_H) */
475